我想在不使用数学模块的情况下找到数字的平方根,因为我需要调用该函数大约20k次并且不想通过在每次调用函数时链接到数学模块来减慢执行速度
有没有更快更容易找到平方根的方法?
Mad*_*ist 29
导入数学模块只发生一次,你可能不会比数学模块快得多.还有一个较旧的Stackoverflow问题,关于Python中的哪个更快:x**.5还是math.sqrt(x)?.目前尚不清楚哪种方法更快.
也许看看NumPy和SciPy,不一定是对于sqrt,但如果你做了一些繁重的计算,它们可能会很方便.
Eri*_*got 10
正如法比安所说的那样,要快得多math.sqrt.原因是它使用CPython调用C库中的对应函数.
但是,您可以通过删除属性查找的开销来加快速度:
from math import sqrt
Run Code Online (Sandbox Code Playgroud)
对sqrt的每次后续调用都不必在math模块中查找,这样可以节省执行时间:
print sqrt(2)
Run Code Online (Sandbox Code Playgroud)
以下是时间数字,从最快到最慢(Python 2.6.5,Mac OS X 10.6.3):sqrt比**0.5以下更快:
lebigot@weinberg ~ % python -m timeit -s 'from math import sqrt; x = 2' 'sqrt(x)'
1000000 loops, best of 3: 0.207 usec per loop
lebigot@weinberg ~ % python -m timeit -s 'x = 2' 'x**0.5'
1000000 loops, best of 3: 0.226 usec per loop
lebigot@weinberg ~ % python -m timeit -s 'import math; x = 2' 'math.sqrt(x)'
1000000 loops, best of 3: 0.268 usec per loop
Run Code Online (Sandbox Code Playgroud)
请注意,时序测试计算变量的平方根.它们不计算常数2**0.5,因为在CPython中2**0.5是预先计算的:
import dis
def f():
return 2**0.5
print dis.dis(f)
Run Code Online (Sandbox Code Playgroud)
版画
2 0 LOAD_CONST 3 (1.4142135623730951)
3 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
你看到常量浮点sqrt(2)= 1.414 ...
如果你操纵数字数组,NumPy sqrt就是要走的路,正如另一个答案所提到的那样.
我认为数学库可能和你自己写的任何东西一样快.但是如果你想自己编写,这里有一个算法.我不懂Python,所以我只会写一些伪代码.
function sqrt(x)
lastGuess=x/2
loop
guess=(lastGuess+x/lastGuess)/2
if abs(guess-lastGuess)<.000001 // or whatever threshold you want
exit loop
lastGuess=guess
return guess
Run Code Online (Sandbox Code Playgroud)
并将伪代码转换为Python:
def sqrt(x):
last_guess= x/2.0
while True:
guess= (last_guess + x/last_guess)/2
if abs(guess - last_guess) < .000001: # example threshold
return guess
last_guess= guess
Run Code Online (Sandbox Code Playgroud)
在某些特殊情况下,您可以将程序大小换成起泡速度.创建一个大型数组并存储每个平方根操作的预先计算结果(使用输入值作为索引).这是非常有限的,但你不会得到更快的东西.
(这就是地震的方式)