• python vs C++ 谁更快


    背景

    1. 我非常喜欢编程语言,之前写过rust、R、python、C++等。
    2. 我的第一门语言就是R语言,然后在比较掌握R语言之后,又花了很长一段时间学习RCPP。
    3. 我觉得不管是会R还是说会python,都应该会C\C++。
    4. C\C++运行效率太顶了。牛!

    主要内容

    最近也刚好C之类的内容,这里就简单分享一个我遇到的非常有意思的内容:使用C和python两种编程语言、通过蒙特卡洛方法计算圆周率PI。

    蒙特卡洛计算圆周率PI

    蒙特卡洛计算圆周率PI其实是一个非常经典的案例,在R仿真里面,也都有。


    基本上案例如下:

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

    那么按照这个思想,只要是不断的生成若干个点,计算占比即可。

    C代码

    这里先分享一个C语言的代码:

    #include 
    #include 
    #include 
    #include 
    
    #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;
    
          radius_squared = x*x + y*y;
          if (radius_squared <= 1) within_circle++;
       }
    
       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(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);
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    这里在clion里面运行一下,可以看到非常的快,基本上都是在0.19秒左右。

    python代码

    既然c语言这么快,那python是什么情况,运行效率如何,这里给到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.",
            type=positive_integer,
            default=1_000_000,
        )
        parser.add_argument(
            "-r",
            "--n_repeats",
            help="Number of times to repeat the calculation.",
            type=positive_integer,
            default=5,
        )
        parser.add_argument(
                "--only-time",
                action='store_true',
                default=False,
        )
        args = parser.parse_args()
    
        run_test(
            args.n_points,
            args.n_repeats,
            args.only_time,
        )
    
    
    if __name__ == "__main__":
        main()
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112

    这里是python的运行结果,基本上在1.5秒左右

    比较与总结

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

    下图是各个版本的python和C语言的运行效率对比:C语言基本上是要比python快个10倍左右。

    其实在科学计算领域,目前最火的就是python和C++。那如果真的是两个都会,确实就无敌了!

    不多说了,我去学习C++了!

  • 相关阅读:
    Istio Arch-1
    C语言习题练习8--二进制&操作符
    Java 17的这些新特性,Java迈入新时代
    JUC第二十八讲:JUC工具类: Semaphore详解
    centos7桌面版下载向日葵和todesk
    k8s中常用命令总结
    如何拆分字符串解析并结构化
    R语言dplyr包高效处理数据-补充函数
    PHP接口自动化测试框架实现
    nonebot2-2.0.0b4 QQ机器人详细教程
  • 原文地址:https://blog.csdn.net/yuanzhoulvpi/article/details/126859918