Python比C ++更快? 这是如何发生的?

这个问题在这里已经有了答案:

  • 为什么读取stdin中的行比C ++慢得多? 10个答案

  • 这里没有什么明显的。 由于Python是用C编写的,它必须使用类似printf东西来实现print 。 C ++ I / O流,如cout ,通常以比printf慢得多的方式实现。 如果你想把C ++放在更好的基础上,你可以尝试改变:

    #include <cstdio>
    int main()
    {
        int x=0;
        while(x!=1000000)
        {
            ++x;
            std::printf("%dn", x);
        }
        return 0;
    }
    

    我改变了使用++x而不是x++ 。 多年前人们认为这是一个值得的“优化”。 如果这种改变对你的程序性能产生了影响(OTOH,我认为使用std::printf会使运行时性能发生巨大变化),我将会有心脏病发作。 相反,我之所以做出这样的改变,仅仅是因为在增加x之前你没有注意x的价值,所以我认为在代码中说这是有用的。


    我的一位同事在工作中告诉我,Python代码比C ++代码更快,然后以此主题为例来证明他的观点。 从其他答案中可以明显看出问题中发布的C ++代码有什么问题。 我仍然想总结一下我的基准测试,以便向他展示一个好的C ++代码的速度!

    原始C ++代码有两个问题:

  • 它使用std::endl在每次迭代中打印一个换行符。 这是一个非常糟糕的想法,因为std::endl比仅仅打印一个换行符做了更多的事情 - 它也迫使流清理到目前为止累积的缓冲区; 冲洗是一项昂贵的操作,因为它必须处理硬件 - 输出设备。 所以第一个解决方法是:如果你想打印一个换行符,只需使用'n'

  • 第二个问题不太明显,因为它在代码中没有看到。 它是在C ++流的设计中。 默认情况下,每次输入和输出操作后,C ++流都会同步到C流,以便您的应用程序可以混合使用std::coutstd::printf ,而std::cinstd::scanf没有任何问题。 这个特性(是的,它是一个特性)在这种情况下是不需要的,所以我们可以禁用它,因为它有一点运行时间开销(这不是问题;它不会使C ++不好;它只是一个价格该功能)。 所以第二个修复是这样的: std::cout::sync_with_stdio(false);

  • 这里是最终的优化代码:

    #include <iostream>
    
    int main()
    {
        std::ios_base::sync_with_stdio(false); 
    
        int x = 0;
        while ( x != 1000000 )
        {
             ++x;
             std::cout << x << 'n';
        }
    }
    

    并用-O3标志编译并运行(和测量 )为:

    $ g++ benchmark.cpp -O3    #compilation
    $ time ./a.out             #run
    
    //..
    
    real   0m32.175s
    user   0m0.088s
    sys    0m0.396s
    

    并运行和测量Python代码(发布在问题中):

    $ time ./benchmark.py
    
    //...
    
    real  0m35.714s
    user  0m3.048s
    sys   0m4.456s
    

    usersys时间告诉我们哪个是快速的, 按什么顺序

    希望能帮助你消除疑虑。 :-)


    我认为我们需要更多的信息,但我希望你正在构建一个未优化的C ++版本。 尝试使用-O3标志来构建它。 (认识GCC的人会有更多更好的建议)。 但是,以下是来自完全不可信来源的时间点:http://ideone.com。 我每5次运行一次,以获得一些时间差异,但只有最初的C ++不尽相同,并且没有太大的变化。

    Python:http://ideone.com/WBWB9时间:0.07-0.07s
    您的C ++:http://ideone.com/tzwQJ时间:0.05-0.06s
    修改后的C ++:http://ideone.com/pXJo3时间:0.00s-0.00s

    至于为什么我的C ++比你更快, std::endl强制C ++立即刷新缓冲区。 'n'没有强制缓冲区刷新的新行,这要快得多。

    (注意:我只跑到12773,因为ideone.com在显示一定数量的输出后杀死进程,这是服务器给我的最多的)

    链接地址: http://www.djcxy.com/p/31507.html

    上一篇: Python faster than C++? How does this happen?

    下一篇: int operators != and == when comparing to zero