我最近在玩timeit和Python的指数时发现了相当多的奇怪之处。你知道吗
首先,我知道数学.sin(1) ==(e**1j)imag,我对它们的相对速度很好奇。以下是我的发现:
>>> timeit('sin(1)', 'from math import sin')
0.12068345113220857
>>> timeit('(e**1j).imag', 'from math import e')
0.27201285586511403
>>> timeit('exp(1j).imag', 'from cmath import exp')
0.25259275173584683
>>> timeit('(2.718281828459045**1j).imag')
0.04272853350335026
这对我来说很奇怪。为什么使用数字本身和**
比其他任何东西都快得多?为什么比罪还快?我知道这不是进口的原因,我完全排除了这一点。同时考虑:
>>> (2.718281828459045**1j).imag
0.8414709848078965
>>> sin(1)
0.8414709848078965
所以,它给出了正确的答案。你知道吗
我决定再深入一点,发现.imag是(2.718281828459045**1j).imag
慢的真正罪魁祸首。事实上
>>> timeit('2.718281828459045**1j')
0.013987474140321865
它似乎没有什么具体的1j;我可以使用2j或0.95j和获得相同的速度。此外,它的速度甚至与复杂和规则的乘法一样快!你知道吗
>>> timeit('1*1j')
0.01617102287718808
>>> timeit('1*1')
0.016536898499907693
我完全糊涂了。当它至少做了同样多的工作(也计算cos)时,它怎么能比sin快这么多呢?怎么能和整数乘法一样快呢?我怀疑部分原因是时间开销的噪音(一定有一个循环),但即使这样也不能解释一切。如果你能帮助我理解,我将不胜感激。你知道吗
您可以通过查看CPython使用dis模块生成的字节码来解释您的观察结果。我们来看看。你知道吗
如您所见,上一个示例非常快,因为在创建字节码时,解释器正在将值转换为常量。上一次你实际上没有做任何工作,除了对
imag
的调用。你知道吗相关问题 更多 >
编程相关推荐