<>背景

* 我非常喜欢编程语言，之前写过rust、R、python、C++等。
* 我的第一门语言就是R语言，然后在比较掌握R语言之后，又花了很长一段时间学习RCPP。
* 我觉得不管是会R还是说会python，都应该会C\C++。
* C\C++运行效率太顶了。牛！
<>主要内容

<>蒙特卡洛计算圆周率PI

* 在一个边长为1的正方形里面，有一个半径为1/2的圆。
* 正方形和圆共一个中心点。圆内切正方形。
* 向这个正方形里面投点，计算点落在圆内的数量。落在圆内点的数量比上总点数就是等于 π / 4 \pi/4 π/4。

<>C代码

#include <stdlib.h> #include <stdio.h> #include <chrono> #include <array>
#define N_POINTS 10000000 #define N_REPEATS 5 float estimate_pi(int n_points) {
double x, y, radius_squared, pi; int within_circle=0; for (int i=0; i <
n_points; i++) { x = (double)rand() / RAND_MAX; y = (double)rand() / RAND_MAX;
pi=(double)within_circle/N_POINTS * 4; return pi; } int main() { double
avg_time = 0; srand(42); for (int i=0; i < N_REPEATS; i++) { auto begin =
std::chrono::high_resolution_clock::now(); double pi = estimate_pi(N_POINTS);
auto end = std::chrono::high_resolution_clock::now(); auto elapsed =
std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin); avg_time +=
elapsed.count() * 1e-9; printf("Pi is approximately %g and took %.5f seconds to
calculate.\n", pi, elapsed.count() * 1e-9); } printf("\nEach loop took on
average %.5f seconds to calculate.\n", avg_time / N_REPEATS); }

<>python代码

import random import time import argparse def estimate_pi( n_points: int,
show_estimate: bool, ) -> None: """ Simple Monte Carlo Pi estimation
calculation. Parameters ---------- n_points number of random numbers used to
for estimation. show_estimate if True, will show the estimation of Pi,
otherwise will not output anything. """ within_circle = 0 for _ in
range(n_points): x, y = (random.uniform(-1, 1) for v in range(2))
radius_squared = x**2 + y**2 if radius_squared <= 1: within_circle += 1
pi_estimate = 4 * within_circle / n_points if not show_estimate: print("Final
Estimation of Pi=", pi_estimate) def run_test( n_points: int, n_repeats: int,
only_time: bool, ) -> None: """ Perform the tests and measure required time.
Parameters ---------- n_points number of random numbers used to for estimation.
n_repeats number of times the test is repeated. only_time if True will only
print the time, otherwise will also show the Pi estimate and a neat formatted
time. """ start_time = time.time() for _ in range(n_repeats):
estimate_pi(n_points, only_time) if only_time: print(f"{(time.time() -
start_time)/n_repeats:.4f}") else: print( f"Estimating pi took {(time.time() -
start_time)/n_repeats:.4f} seconds per run." ) def positive_integer(value: str)
-> int: """Check for positive integer in arg_parse.""" int_value = int(value)
if int_value <= 0: raise argparse.ArgumentTypeError(f"{value} is an invalid
positive int value") return int_value def main(arguments=None): """Main loop in
arg parser.""" parser = argparse.ArgumentParser() parser.add_argument( "-p",
"--n_points", help="Number of random points to use for estimating Pi.",
"--n_repeats", help="Number of times to repeat the calculation.",
action='store_true', default=False, ) args = parser.parse_args() run_test(
args.n_points, args.n_repeats, args.only_time, ) if __name__ == "__main__":
main()

<>比较与总结

* 上面两个其实都不太公平，因为我的C语言代码是在WSL2里面运行的，cpu都是有损耗的情况下。跑出个0.19秒。
* 上面的python代码我是直接使用anaconda环境跑的。跑出个1.5秒左右。
* 基本上C语言的运行时间是python的10倍左右。
* 其实大家如果直接看上面的C代码，发现好像C语言代码也没那么难读。C语言的语法看着还挺现代的。

GitHub

Gitee