当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《哪个在Python中更快:x**.5还是math.sqrt(x)?》经验,为你挑选了5个好方法。

我一直在想这个问题.正如标题所说,哪个更快,实际功能还是简单地提升到半功率?

UPDATE

这不是过早优化的问题.这只是底层代码实际工作原理的问题.Python代码的工作原理是什么?

我发送了Guido van Rossum电子邮件,因为我真的很想知道这些方法的不同之处.

我的电子邮件:

在Python中至少有3种方法可以做平方根:math.sqrt,'**'运算符和pow(x,.5).我只是好奇每个实现的差异.谈到效率哪个更好?

他的回答是:

pow和**是等价的; math.sqrt不适用于复数,也不适用于C sqrt()函数的链接.至于哪一个更快,我不知道......

Claudiu.. 82

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

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 vs. 0.139000

psyco似乎也math.sqrt更好:

Python 2.5 + Psyco 2.0: 0.109000 vs. 0.043000

Python 2.6 + Psyco 2.0: 0.128000 vs. 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从带有tox.ini文件的目录运行.

标准的timeit模块是你的朋友.它避免了测量执行时间时常见的陷阱! (8认同)

键盘是一项很棒的服务,但对于时序性能来说很糟糕,我的意思是谁知道服务器在特定时刻会有多忙.每次运行都可能产生非常不同的结果 (2认同)


jfs.. 18

第一条优化规则:不要这样做

第二条规则:不这样做,但

这是一些时间(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

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


Kibbee.. 10

你真正表现了多少平方根?您是否正在尝试用Python编写一些3D图形引擎?如果没有,那么为什么要使用易于阅读的代码隐藏的代码呢?时间差异将小于任何人可能会注意到的任何我可以预见的应用程序.我真的不是故意放下你的问题,但似乎你因为过早优化而走得太远了.



1> Claudiu..:

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

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 vs. 0.139000

psyco似乎也math.sqrt更好:

Python 2.5 + Psyco 2.0: 0.109000 vs. 0.043000

Python 2.6 + Psyco 2.0: 0.128000 vs. 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从带有tox.ini文件的目录运行.


标准的timeit模块是你的朋友.它避免了测量执行时间时常见的陷阱!
键盘是一项很棒的服务,但对于时序性能来说很糟糕,我的意思是谁知道服务器在特定时刻会有多忙.每次运行都可能产生非常不同的结果

2> jfs..:

第一条优化规则:不要这样做

第二条规则:不这样做,但

这是一些时间(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

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



3> Kibbee..:

你真正表现了多少平方根?您是否正在尝试用Python编写一些3D图形引擎?如果没有,那么为什么要使用易于阅读的代码隐藏的代码呢?时间差异将小于任何人可能会注意到的任何我可以预见的应用程序.我真的不是故意放下你的问题,但似乎你因为过早优化而走得太远了.


我真的不觉得我在做一个过早的优化.这是一个简单的问题,从2种不同的方法决定,平均来说会更快.
如果他在Python中制作3D引擎怎么办?
我不认为**操作员是神秘的.我认为向指数0.5提出一些东西,作为一种让平方根对那些跟不上数学的人有点神秘的方法.
Kibbee:这绝对是一个有效的问题,但我对Stack Overflow上的问题数量感到沮丧,这意味着提问者正在进行各种过早的优化.对于每种语言,这绝对是问题的很大一部分.
math.sqrt(x)比x**0.5更容易阅读吗?我认为它们显然都是平方根...至少如果你熟悉python的话.不要因为你不熟悉python而调用标准的python运算符,比如**"神秘".

4> JimB..:

在这些微基准测试中,math.sqrt会更慢,因为在math命名空间中查找sqrt所需的时间很短.您可以稍微改善它

 from math import sqrt

尽管如此,通过timeit运行一些变化,显示"x**.5"的轻微(4-5%)性能优势

有趣的是,做

 import math
 sqrt = math.sqrt

将速度加快,速度差异在1%以内,具有非常小的统计意义.

我将重复Kibbee,并说这可能是一个不成熟的优化.



5> zoli2k..:

在python 2.6中,该(float).__pow__() 函数使用C pow()函数,math.sqrt()函数使用C sqrt()函数.

在glibc编译器中,实现pow(x,y)非常复杂,并且针对各种异常情况进行了很好的优化.例如,调用C pow(x,0.5)只调用该sqrt()函数.

使用.**math.sqrt由C函数周围使用的包装器和速度引起的速度差异很大程度上取决于系统上使用的优化标志/ C编译器.

编辑:

以下是我机器上Claudiu算法的结果.我得到了不同的结果:

zoltan@host:~$ python2.4 p.py 
Took 0.173994 seconds
Took 0.158991 seconds
zoltan@host:~$ python2.5 p.py 
Took 0.182321 seconds
Took 0.155394 seconds
zoltan@host:~$ python2.6 p.py 
Took 0.166766 seconds
Took 0.097018 seconds

推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有