Python中哪个更快:x**.5还是math.sqrt(x)?
我一直在想这个问题。正如标题所说,实际的函数和简单地开平方,哪个更快呢?
更新
这不是关于过早优化的问题。这只是一个关于底层代码实际如何工作的疑问。Python代码的工作原理是什么?
我给Guido van Rossum发了一封邮件,因为我真的想知道这些方法之间的区别。
我的邮件:
在Python中,至少有三种方法可以计算平方根:math.sqrt、'**'运算符和pow(x,.5)。我只是好奇这些方法的实现有什么不同。在效率方面,哪个更好呢?
他的回复:
pow和'**'是等价的;math.sqrt不适用于复数,并且与C语言的sqrt()函数有关。至于哪个更快,我就不知道了……
15 个回答
18
在这些微基准测试中,math.sqrt
会比较慢,因为它需要花一点时间去查找数学库里的 sqrt
函数。你可以通过以下方法稍微提高它的速度:
from math import sqrt
即便如此,通过 timeit
运行几个不同的测试,结果显示 x**.5
的性能还是稍微好一些,大约快了 4-5%。
有趣的是,使用以下方法:
import math
sqrt = math.sqrt
速度提升得更明显,差距缩小到只有 1% 左右,而且统计上几乎没有显著性。
我会重复 Kibbee 的观点,这可能算是一种过早的优化。
30
- 优化的第一条规则:别去做
- 第二条规则:别去做,还不行
这里有一些时间测试(Python 2.5.2,Windows):
$ python -mtimeit -s"from math import sqrt; x = 123" "x**.5"
1000000 loops, best of 3: 0.445 usec per loop
$ python -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
1000000 loops, best of 3: 0.574 usec per loop
$ python -mtimeit -s"import math; x = 123" "math.sqrt(x)"
1000000 loops, best of 3: 0.727 usec per loop
这个测试显示,x**.5
比 sqrt(x)
稍微快一点。
但在 Python 3.0 中,结果正好相反:
$ \Python30\python -mtimeit -s"from math import sqrt; x = 123" "x**.5"
1000000 loops, best of 3: 0.803 usec per loop
$ \Python30\python -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
1000000 loops, best of 3: 0.695 usec per loop
$ \Python30\python -mtimeit -s"import math; x = 123" "math.sqrt(x)"
1000000 loops, best of 3: 0.761 usec per loop
在另一台机器上(Ubuntu,Python 2.6 和 3.1),math.sqrt(x)
总是比 x**.5
快:
$ python -mtimeit -s"from math import sqrt; x = 123" "x**.5"
10000000 loops, best of 3: 0.173 usec per loop
$ python -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
10000000 loops, best of 3: 0.115 usec per loop
$ python -mtimeit -s"import math; x = 123" "math.sqrt(x)"
10000000 loops, best of 3: 0.158 usec per loop
$ python3.1 -mtimeit -s"from math import sqrt; x = 123" "x**.5"
10000000 loops, best of 3: 0.194 usec per loop
$ python3.1 -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
10000000 loops, best of 3: 0.123 usec per loop
$ python3.1 -mtimeit -s"import math; x = 123" "math.sqrt(x)"
10000000 loops, best of 3: 0.157 usec per loop
125
math.sqrt(x)
的速度明显比 x**0.5
快。
import math
N = 1000000
%%timeit
for i in range(N):
z=i**.5
进行了10次循环,最好的结果是每次循环156毫秒
%%timeit
for i in range(N):
z=math.sqrt(i)
进行了10次循环,最好的结果是每次循环91.1毫秒
使用的是Python 3.6.9(笔记本)。