Python - 使用内置命令与数学模块进行数学运算

时间:2014-01-22 17:27:59

标签: python performance python-2.7

如果x是数字。在python x**(1/2.0) [甚至x**(0.5)]和sqrt(x)中做同样的事情。两种方法都将返回给定数字的平方根。虽然我们必须导入数学模块(sqrt),但form math import sqrt可以工作。有没有理由使用其他方法?我想知道:因为sqrt()必须进口才能更快?

3 个答案:

答案 0 :(得分:4)

如果计算常数整数的平方根,**运算符可能比sqrt快几倍,但是当使用变量时,sqrt**更快}和math.sqrt

In [38]: %timeit -n1000000 3**.5
1000000 loops, best of 3: 46.7 ns per loop

In [39]: %timeit -n1000000 sqrt(3)
1000000 loops, best of 3: 312 ns per loop

In [40]: %timeit -n1000000 math.sqrt(3)
1000000 loops, best of 3: 377 ns per loop

In [41]: x=3

In [42]: %timeit -n1000000 x**.5
1000000 loops, best of 3: 469 ns per loop

In [43]: %timeit -n1000000 sqrt(x)
1000000 loops, best of 3: 327 ns per loop

In [44]: %timeit -n1000000 math.sqrt(x)
1000000 loops, best of 3: 430 ns per loop

答案 1 :(得分:1)

如果您想直接查看python字节码以深入了解这些差异,我建议使用dis模块。这是一个示例,显示为什么数学版本不同。

>>> import math
>>> import dis
>>>
>>> def builtin(number):
...     return number ** 0.5
... 
>>> def with_math(number):
...     return math.sqrt(number)
... 
>>> dis.dis(builtin)
  2           0 LOAD_FAST                0 (number)
              3 LOAD_CONST               1 (0.5)
              6 BINARY_POWER        
              7 RETURN_VALUE        
>>> dis.dis(with_math)
  2           0 LOAD_GLOBAL              0 (math)
              3 LOAD_ATTR                1 (sqrt)
              6 LOAD_FAST                0 (number)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE  

with_math选项中的前两个命令应该被忽略,因为它们不会在每次实际调用时发生。但是你可以看到这两个函数实际上非常相似。主要区别在于数学版本用LOAD_CONST替换BINARY_POWERCALL_FUNCTION。虽然查找会使这个开始变慢,但math版本从长远来看会更快,因为你可以在很大程度上忽略前6个周期。

答案 2 :(得分:0)

这完全取决于你想做什么

对于一个简单的表达式,运算符可能会超出math.sqrt,但如果需要用作回调,则使用math.sqrt执行与使用运算符的lambda相比将会表现更好

In [4]: %timeit math.sqrt(3)
10000000 loops, best of 3: 148 ns per loop

In [5]: %timeit 3**.5
100000000 loops, best of 3: 19.5 ns per loop

In [12]: %timeit -n 1000 map(lambda e: e**.5, range(1,100))
1000 loops, best of 3: 31.3 us per loop

In [13]: %timeit -n 1000 map(math.sqrt, range(1,100))
1000 loops, best of 3: 14.6 us per loop