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

2024-04-27 04:33:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我想这件事已经有一段时间了。正如题目所说,哪个更快,实际功能还是简单地提高到一半功率?

更新

这不是一个过早优化的问题。这只是一个关于底层代码如何实际工作的问题。Python代码的工作原理是什么?

我给Guido van Rossum发了一封邮件,因为我真的很想知道这些方法的区别。

我的电子邮件:

There are at least 3 ways to do a square root in Python: math.sqrt, the '**' operator and pow(x,.5). I'm just curious as to the differences in the implementation of each of these. When it comes to efficiency which is better?

他的回答是:

pow and ** are equivalent; math.sqrt doesn't work for complex numbers, and links to the C sqrt() function. As to which one is faster, I have no idea...


Tags: andoftheto代码in功能which
3条回答
  • 优化的第一条规则:不要这样做
  • 第二条规则:不要这样做

下面是一些计时(Python2.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)稍快。

对于Python3.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

math.sqrt(x)总是比另一台机器(Ubuntu、Python 2.6和3.1)上的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

你到底在表演多少平方根?你想用Python编写一些3D图形引擎吗?如果不是,那为什么要使用比容易阅读的代码更神秘的代码呢?时间差是任何人都不会注意到的,在任何我可以放弃的申请。我真的不想放下你的问题,但你似乎有点过分过早的优化。

根据评论,我更新了代码:

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变量那样经历查找的开销。但我可能错了:

Python2.5:0.191000对0.224000

Python 2.6:0.195000对0.139000

同时,psyco似乎处理得更好:

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

要复制结果:

  • 获取源:^{}
  • 安装^{}pip install tox
  • 使用tox.ini文件从目录中运行tox

相关问题 更多 >