用蒙特卡洛法计算圆周率的近似值效率对比
  • 板块灌水区
  • 楼主CleanIce
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/12/1 19:09
  • 上次更新2023/12/1 21:06:15
查看原帖
用蒙特卡洛法计算圆周率的近似值效率对比
821660
CleanIce楼主2023/12/1 19:09

任务

利用蒙特卡洛法计算圆周率 π\pi 的近似值。

具体计算方法如下:

  1. 令 n=0n = 0,NN 为任意正整数(即 N∈N+N \in \mathbb{N}^+)。NN 即计算点数,点数越大计算的 π\pi 越精确。
  2. 随机取 [0,1)[0, 1) 之间的浮点数 xx。
  3. 随机取 [0,1)[0, 1) 之间的浮点数 yy。
  4. 计算 m=x2+y2m = x^2 + y^2。
  5. 若 m≤1m \le 1,令 n←n+1n \gets n + 1。
  6. 重复步骤 2 到 5 共 NN 次。
  7. 计算 p=4nNp = \frac{4n}{N}。最后,NN 越大,pp 就越和 π\pi 近似。

语言及版本

下面列出参与实验的所有编程语言及其版本,其中竖线(|)之后的为最低可运行版本。

请注意版本差异带来的效率差异。

  1. C18 (GCC13.1) | C99 (GCC5.1 clang3.0 MSVC2013-12.0)
  2. C++23 (GCC13.1) | C++20 (GCC10.1 clang10.0 MSVC2019-16.x)
  3. Java20 | Java8
  4. Python3.12 | Python3.6
  5. PyPy3.10 | PyPy3.6
  6. JavaScript ES10 (node18.13.0) | JavaScript ES5 (node4.0.0)
  7. Julia1.9.2 | Julia1.0
  8. Go1.13.5 | Go1.0
  9. C#6.0 (.NET 8.0.100) | C#6.0 (.NET Framework 4.0) (.NET Core 1.0) (.NET 5.0)

注意几个点:

  1. 只有 C#6.0 及以上的版本允许省略 using System; 语句。
  2. Python 的类型注解,如果出现警告,可以改用 typing 库的 Tuple。将 tuple[float, float] 替换为 Tuple[float, float]。这是版本问题。
  3. JavaScript 语言解释器 Node.js 确保安装了 readline 模块。
  4. C、C++ 的 O2 优化也参与实验。

源代码

源代码很多,所以我放在了云剪贴板。

影响效率的因素

下面给出影响计算效率的因素。我们只计时蒙特卡洛整个计算的时间,因此不包括输入输出等代码的耗时。您可以查看源代码了解。

  1. 语言本身的效率。
  2. 随机数的效率。一般来说可以忽略不计,因为所用的算法都是伪随机数算法。要有影响也是语言本身的效率影响。

另外,计算机配置也是一大因素。这里给出计算机配置:

  1. 处理器:Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz 1.80 GHz
  2. RAM(内存):16.0 GB
  3. 系统:Windows 11 家庭中午版(22H2 22621.2715)(64 位操作系统)

本来想在 Ubuntu 虚拟机上测试的(Linux 系统测试更精确),但是我没下也没有那么多空间下载这么多语言编译器或解释器,所以就在 Windows 主机上进行了测试。Ubuntu 虚拟机主要是给我做开发的。

我用于测试的编译器和解释器都是 64 位的,所以不存在字长导致的效率差异。

测试结果

我们测试了不同点数(分别是 10510^5、10610^6、10710^7 和 10810^8)下各种语言的蒙特卡洛算法的耗时并进行了排序。以下表格便是结果。为了简便,我们只显示语言名称和其用时,不包括语言版本。对于相同耗时的语言,我们令其并列。

N=105N = 10^5N=106N = 10^6N=107N = 10^7N=108N = 10^8
1Julia (0ms)Julia (8ms)Julia (42ms)Julia (349ms)
2C# (3ms)C# (12ms)C# (95ms)C# (887ms)
3C++ O2 & Go (4ms)C++ O2 (20ms)C++ O2 (193ms)C++ O2 (1641ms)
4/Go (35ms)JavaScript (245ms)JavaScript (2202ms)
5C O2 (8ms)JavaScript (36ms)PyPy (298ms)PyPy (2972ms)
6C (9ms)C O2 & Java & PyPy (41ms)C O2 (337ms)C O2 (3327ms)
7Java & PyPy (10ms)/Go (353ms)Java (3726ms)
8//C (386ms)C (3865ms)
9JavaScript (14ms)C (58ms)Java (392ms)Go (4014ms)
10C++ (34ms)C++ (303ms)C++ (2885ms)C++ (29013ms)
11Python (58ms)Python (441ms)Python (4388ms)Python (56138ms)

再给出一张横向排名表:

N=105N = 10^5N=106N = 10^6N=107N = 10^7N=108N = 10^8
C6988
C O25666
C++10101010
C++ O23333
Java7697
Python11111111
PyPy7655
JavaScript9544
Julia1111
Go3479
C#2222

The End

2023/12/1 19:09
加载中...