PyPy显示不准确的基准测试结果?

thk*_*ang 2 python benchmarking pypy

我正在研究Project Euler,并想知道我是否可以使用PyPy来加速我的解决方案.但是,我发现结果非常令人失望,因为它需要更多时间来计算.

d:\projeuler>pypy problem204.py
3462.08630405 mseconds

d:\projeuler>python problem204.py
1823.91602542 mseconds
Run Code Online (Sandbox Code Playgroud)

由于mseconds输出是使用python的time模块计算的,所以我使用内置的基准测试命令再次运行它.

d:\projeuler>pypy -mtimeit -s "import problem204" "problem204._main()"
10 loops, best of 3: 465 msec per loop

d:\projeuler>python -mtimeit -s "import problem204" "problem204._main()"
10 loops, best of 3: 1.87 sec per loop
Run Code Online (Sandbox Code Playgroud)

PyPy报告称完成运行需要大约半秒钟.但是,我尝试了多次运行pypy problem204,输出甚至从未接近基准测试.5秒.与pypy不同,python的mtimeit结果与输出一致.pypy给了我不准确的基准,还是有些魔法我不明白?

小智 5

注意timeit

  1. 多次运行语句(在你的情况下为10),和
  2. 这样做了几次(默认为3次)并且由于文档中概述的原因而给出了最小值.

这取决于你的代码,但完全有可能JIT编译器应该归咎于这个令人困惑的结果.每次启动新的pypy进程时都会产生JIT预热开销,但在timeit基准测试期间只会发生一次(因为_main在同一进程中运行多次).此外,如果代码的某些部分经常运行,以至于在_main运行一次时没有编译,但只有在运行时(例如,三次),后续运行也会更快,这进一步消除了第一个的最佳结果(即一次跑步pypy problem204.py).

timeit结果是正确的,因为它(大致)相匹配的代码将如何快速在最好的情况下-暖机的JIT编译器,在CPU很少输给其他程序,等等你的问题是,你想知道的东西不同-时间包括JIT热身.

  • +1。如果您需要比较像 Web 应用程序一样无限期运行的程序的子例程的速度,以及像这样运行一次的程序的命令行“time”包装器(不是 python 模块),我会使用“timeit” . (2认同)