我想了很久了。就像题目说的,哪个更快,是实际函数还是简单地取1 / 2次幂?

更新

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

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

我的电子邮件:

在Python中至少有3种方法来求平方根:math。返回值, '**'运算符和pow(x,.5)。我只是好奇它们之间的区别 每一个的实现。说到效率 是更好吗?

他的回答:

Pow和**是等价的;数学。根号方根不适用于复数, 并链接到C的sqrt()函数。至于哪一个是 快点,我不知道……


当前回答

如果您进入math.py并将函数“sqrt”复制到您的程序中,则会更快。程序找到math.py,然后打开它,找到要找的函数,然后将其带回程序,这需要时间。如果该函数即使使用“查找”步骤也更快,那么函数本身必须非常快。可能会让你的时间缩短一半。总而言之:

转到math.py 找到函数“√” 复制它 将函数粘贴到程序中作为根号查找器。 它的时间。

其他回答

当然,如果要处理字面量并且需要一个常量值,Python运行时可以在编译时预先计算该值,如果它是用操作符编写的——在这种情况下不需要分析每个版本:

In [77]: dis.dis(a)                                                                                                                       
  2           0 LOAD_CONST               1 (1.4142135623730951)
              2 RETURN_VALUE

In [78]: def a(): 
    ...:     return 2 ** 0.5 
    ...:                                                                                                                                  

In [79]: import dis                                                                                                                       

In [80]: dis.dis(a)                                                                                                                       
  2           0 LOAD_CONST               1 (1.4142135623730951)
              2 RETURN_VALUE

Math.sqrt (x)比x**0.5快得多。

import math
N = 1000000
%%timeit
for i in range(N):
    z=i**.5

10个循环,最好的3:156毫秒每循环

%%timeit
for i in range(N):
    z=math.sqrt(i)

10个循环,最好的3:91.1毫秒每循环

使用Python 3.6.9(笔记本)。

很可能是math.sqrt(x),因为它针对平方根进行了优化。

基准测试将为您提供您正在寻找的答案。

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

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

**或数学使用速度的差异。sqrt是由围绕C函数的包装器引起的,速度很大程度上取决于系统上使用的优化标志/C编译器。

编辑:

这是克劳狄算法在我机器上的结果。我得到了不同的结果:

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

克劳狄的结果和我的不一样。我在一台旧的P4 2.4Ghz机器上使用Ubuntu上的Python 2.6…以下是我的结果:

>>> timeit1()
Took 0.564911 seconds
>>> timeit2()
Took 0.403087 seconds
>>> timeit1()
Took 0.604713 seconds
>>> timeit2()
Took 0.387749 seconds
>>> timeit1()
Took 0.587829 seconds
>>> timeit2()
Took 0.379381 seconds

对我来说,SQRT一直都更快……甚至Codepad.org现在似乎也同意,在本地环境下,根号rt更快(http://codepad.org/6trzcM3j)。Codepad目前运行的是Python 2.5。也许克劳狄第一次回答的时候,他们使用的是2.4或更老的版本?

事实上,即使使用math.sqrt(i)来代替arg(i),我仍然可以得到更好的sqrt。在本例中,timeit2()在我的机器上花费了0.53到0.55秒,这仍然比timeit1的0.56-0.60秒要好。

我会说,在现代Python中,使用数学。一定要把它带入本地环境,或者用somevar=math。或者从数学导入根号。