【发布时间】:2011-12-25 11:08:25
【问题描述】:
在优化我的代码时,我意识到以下几点:
>>> from timeit import Timer as T
>>> T(lambda : 1234567890 / 4.0).repeat()
[0.22256922721862793, 0.20560789108276367, 0.20530295372009277]
>>> from __future__ import division
>>> T(lambda : 1234567890 / 4).repeat()
[0.14969301223754883, 0.14155197143554688, 0.14141488075256348]
>>> T(lambda : 1234567890 * 0.25).repeat()
[0.13619112968444824, 0.1281130313873291, 0.12830305099487305]
还有:
>>> from math import sqrt
>>> T(lambda : sqrt(1234567890)).repeat()
[0.2597470283508301, 0.2498021125793457, 0.24994492530822754]
>>> T(lambda : 1234567890 ** 0.5).repeat()
[0.15409398078918457, 0.14059877395629883, 0.14049601554870605]
我认为这与 python 在 C 中实现的方式有关,但我想知道是否有人愿意解释为什么会这样?
【问题讨论】:
-
您接受的问题的答案(我假设它回答了您的真实问题)与您的问题标题没有太大关系。你可以编辑它以与不断折叠有关吗?
-
@ZanLynx - 嗨。你介意澄清一下吗?我发现问题标题准确地表达了我想知道的内容(为什么 X 比 Y 快)并且我选择的答案正是如此......似乎与我完美匹配......但也许我忽略了一些东西?
-
乘法和幂函数总是比除法和 sqrt() 函数更快,因为它们的本质。除法和根运算一般要使用一系列越来越精细的近似,不能像乘法那样直接得到正确答案。
-
我觉得问题标题应该说明值都是字面常量这一事实,事实证明这是答案的关键。在典型的硬件上,整数和 FP 乘法和加法/减法很便宜; integer 和 FP div 和 FP sqrt 都很昂贵(可能比 FP mul 低 3 倍的延迟和 10 倍的吞吐量)。 (大多数 CPU 在硬件中将这些操作作为单个 asm 指令实现,这与 cube-root 或 pow() 之类的不同)。
-
但如果 Python 解释器开销仍然使 mul 和 div asm 指令之间的差异相形见绌,我不会感到惊讶。有趣的事实:在 x86 上,FP 除法通常比整数除法性能更高。 (agner.org/optimize)。 Intel Skylake 上的 64 位整数除法具有 42-95 个周期的延迟,而 32 位整数为 26 个周期,而双精度 FP 为 14 个周期。 (64 位整数乘法是 3 个周期延迟,FP mul 是 4)。吞吐量差异甚至更大(int/FP mul 和 add 都至少每个时钟一个,但除法和 sqrt 没有完全流水线化。)
标签: python c performance python-2.7 python-internals