使用math.sqrt(num)而不是Python中的num ** 0.5是否有任何优势

时间:2013-11-26 19:58:55

标签: python

我看到人们通常使用math库来计算平方根,我想知道在普通**0.5上是否有优势(matissa或计算效率)?

好的还做了快速测试,cpu时间趋于平等

import time 

start_time = time.clock()

i = 0
while i < 10000000: 
    i ** 0.5
    i += 1

elapsed_time = time.clock() - start_time
print ("Time elapsed: {} seconds".format(elapsed_time))

经过的时间:7.27秒

import time 
import math

start_time = time.clock()

i = 0
while i < 10000000: 
    math.sqrt(i)
    i += 1

elapsed_time = time.clock() - start_time
print ("Time elapsed: {} seconds".format(elapsed_time))

已用时间:7.109999999999999秒

5 个答案:

答案 0 :(得分:2)

看起来函数调用更快:

In [102]: a = 2

In [103]: timeit a**0.5
1000000 loops, best of 3: 222 ns per loop

In [104]: timeit sqrt(a)
10000000 loops, best of 3: 120 ns per loop

除了可读性之外,我想不出任何其他原因。哪个更具可读性取决于您的要求和背景。

答案 1 :(得分:2)

他们的行为是微妙的差异。 x ** n首先尝试x.__pow__(n)。如果该调用返回NotImplemented,则调用n.__rpow__(x)

>>> (2).__pow__(0.5)
NotImplemented
>>> (0.5).__rpow__(2)
1.4142135623730951

math.sqrt(x)将x转换为float(幕后的C double),然后调用C数学库。

>>> class F(object):
...   def __init__(self, value):
...     self.value = value
...   def __float__(self):
...     print("hi!")
...     return float(self.value)
... 
>>> a=F(2)
>>> math.sqrt(a)
hi!
1.4142135623730951

对于Python中的普通数字类型,差异通常并不重要,但其他数字类型的行为可能不同。 gmpy2为整数和浮点实现任意精度算术。导致math.sqrt()溢出的值可由**。

处理
>>> import gmpy2
>>> math.sqrt(gmpy2.mpz("1"*999))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: 'mpz' too large to convert to float
>>> gmpy2.mpz("1"*999)**0.5
mpfr('1.0540925533894598e+499')
>>> 

答案 2 :(得分:0)

根据math.pow(x,[b])的描述,我会冒成math.sqrt(x)进行自动类型转换的危险。一般来说,我的猜测是数学库比使用** 0.5

更安全,更可靠

答案 3 :(得分:0)

他们大致相同:

$ python -m timeit 'import math; [math.sqrt(n) for n in range(100)]'
100000 loops, best of 3: 13.3 usec per loop
$ python -m timeit 'import math; [n**0.5 for n in range(100)]'
100000 loops, best of 3: 16.2 usec per loop

答案 4 :(得分:0)

在不了解python的情况下,我会说运算符比在你只执行一次的情况下调用库函数更好,因为使用运算符意味着你的解释器(或其他语言的编译器)不会必须通过整个包含的图书馆。