2

我在Project Euler上工作,想知道是否可以使用 PyPy 加速我的解决方案。但是,我发现结果非常令人失望,因为计算需要更多时间。

d:\projeuler>pypy problem204.py
3462.08630405 mseconds

d:\projeuler>python problem204.py
1823.91602542 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

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

4

1 回答 1

5

请注意,timeit

  1. 多次运行该语句(在您的情况下为 10 次),并且
  2. 这样做几次(默认情况下为 3 次)并给出最少的次数,原因在文档中列出

这取决于您的代码,但完全有可能 JIT 编译器要为这个令人困惑的结果负责。每次启动一个新的 pypy 进程时都会产生 JIT 预热开销,但在 timeit 基准测试期间只有一次(因为_main在同一进程中运行多次)。此外,如果您的代码的某些部分运行得太频繁以至于它在_main运行一次时没有被编译,而是仅在运行 3 次时才编译,那么后续运行也会更快,这会进一步消除第一次运行的最佳结果(即运行pypy problem204.py一次的那个)。

结果timeit是正确的,因为它(大致)匹配代码在最佳情况下的速度 - 预热的 JIT 编译器,很少将 CPU 丢失给其他程序等。你的问题是你想知道一些不同的东西 -时间包括 JIT 预热。

于 2012-11-01T16:04:46.963 回答