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