Python中更快:x **。5或math.sqrt(x)?
我一直在想这个。 正如标题所说,哪个更快,实际功能还是简单地提高到一半的功率?
UPDATE
这不是过早优化的问题。 这只是底层代码实际工作的问题。 Python代码的工作原理是什么?
我给Guido van Rossum发了一封电子邮件,因为我真的很想知道这些方法的不同之处。
我的电子邮件:
至少有三种方法可以在Python中做平方根:math.sqrt,'**'运算符和pow(x,.5)。 我只是好奇于每个实现的差异。 谈到效率更好?
他的回应是:
战俘和**是等同的; math.sqrt不适用于复数,并且链接到C sqrt()函数。 至于哪一个更快,我不知道...
根据评论,我更新了代码:
import time
import math
def timeit1():
s = time.time()
for i in xrange(750000):
z=i**.5
print "Took %f seconds" % (time.time() - s)
def timeit2(arg=math.sqrt):
s = time.time()
for i in xrange(750000):
z=arg(i)
print "Took %f seconds" % (time.time() - s)
timeit1()
timeit2()
现在, math.sqrt
函数直接在本地参数中,这意味着它有最快的查找可能性。
更新: python版本似乎在这里。 我曾经认为timeit1
会更快,因为当python解析“i **。5”时,它会在语法上知道调用哪种方法( __pow__
或某种变体),因此它不必经历查找的开销math.sqrt
变体确实。 但我可能是错的:
Python 2.5: 0.191000 vs. 0.224000
Python 2.6: 0.195000与0.139000
另外psyco似乎更好地处理math.sqrt
:
Python 2.5 + Psyco 2.0: 0.109000与0.043000
Python 2.6 + Psyco 2.0: 0.128000与0.067000
| Interpreter | x**.5, | sqrt, | sqrt faster, % |
| | seconds | seconds | |
|----------------+---------+---------+----------------|
| Python 3.2rc1+ | 0.32 | 0.27 | 19 |
| Python 3.1.2 | 0.136 | 0.088 | 55 |
| Python 3.0.1 | 0.155 | 0.102 | 52 |
| Python 2.7 | 0.132 | 0.079 | 67 |
| Python 2.6.6 | 0.121 | 0.075 | 61 |
| PyPy 1.4.1 | 0.083 | 0.0159 | 422 |
| Jython 2.5.1 | 0.132 | 0.22 | -40 |
| Python 2.5.5 | 0.129 | 0.125 | 3 |
| Python 2.4.6 | 0.131 | 0.123 | 7 |
#+TBLFM: $4=100*($2-$3)/$3;%.0f
在机器上产生的表格结果:
$ uname -vms
Linux #42-Ubuntu SMP Thu Dec 2 02:41:37 UTC 2010 x86_64
$ cat /proc/cpuinfo | grep 'model name' | head -1
model name : Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
重现结果:
git clone git://gist.github.com/783011.git gist-783011
tox
: pip install tox
tox.ini
文件从目录运行tox
。 这里有一些时间(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,结果是相反的:
$ Python30python -mtimeit -s"from math import sqrt; x = 123" "x**.5"
1000000 loops, best of 3: 0.803 usec per loop
$ Python30python -mtimeit -s"from math import sqrt; x = 123" "sqrt(x)"
1000000 loops, best of 3: 0.695 usec per loop
$ Python30python -mtimeit -s"import math; x = 123" "math.sqrt(x)"
1000000 loops, best of 3: 0.761 usec per loop
math.sqrt(x)
总是比另一台机器上的x**.5
快(Ubuntu,Python 2.6和3.1):
$ 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
你真的有多少根方根? 你想用Python编写一些3D图形引擎吗? 如果不是,那么为什么要使用易于阅读的代码来隐藏代码? 在任何我可以预见的应用程序中,时间差都比任何人都可以注意到的要小。 我真的不打算放下你的问题,但似乎你过早的优化会有点过分。
链接地址: http://www.djcxy.com/p/39623.html