Python中哪个更快:x**.5还是math.sqrt(x)?

250 投票
15 回答
120589 浏览
提问于 2025-04-11 20:02

我一直在想这个问题。正如标题所说,实际的函数和简单地开平方,哪个更快呢?

更新

这不是关于过早优化的问题。这只是一个关于底层代码实际如何工作的疑问。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**.5sqrt(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(笔记本)。

撰写回答