我想在不使用数学模块的情况下找到数字的平方根,因为我需要调用函数约20k次,并且不希望每次调用函数时都通过链接到数学模块来减慢执行的速度如何在不使用数学模块的情况下执行平方根?
找到平方根有没有更快更简单的方法?
我想在不使用数学模块的情况下找到数字的平方根,因为我需要调用函数约20k次,并且不希望每次调用函数时都通过链接到数学模块来减慢执行的速度如何在不使用数学模块的情况下执行平方根?
找到平方根有没有更快更简单的方法?
导入数学模块只发生一次,你可能不会比数学模块快得多。还有一个关于Which is faster in Python: x**.5 or math.sqrt(x)?的较旧的Stackoverflow问题。目前还不清楚哪种方法更快。
你可以实现牛顿的方法,但是,虽然速度非常快,但它不可能比我假设在数学模块中实现的C版本更快。见http://en.wikipedia.org/wiki/Methods_of_computing_square_roots。
使用电源操作,并提高数字的1/2功率:
>>> 2**0.5
1.4142135623730951
至于是否会更快:
>>> timeit.timeit(stmt='sqrt(x)', setup='from math import sqrt; x = 2')
0.7182440785071833
>>> timeit.timeit(stmt='x**0.5', setup='from math import sqrt; x = 2')
0.87514279049432275
我在我的电脑上得到了类似的结果,但是当我从我接受的问题的接受答案中尝试基准时,math.sqrt更快。这里有一些有趣的事情发生。 – 2010-06-15 16:42:38
这些时间测试不是很有代表性:你可以看到我的答案,它表明'** 0.5'实际上比'math.sqrt'慢。原因是'2 ** 0.5'是一个预先计算的数值常数。 – EOL 2010-06-15 17:21:21
@EOL - 我得到与其他数字相似的结果(即,“0.42521 ** 0.5”大约比“sqrt(0.42521)”快7倍)。我没有得出任何结论,但测试似乎对我有效。 – Seth 2010-06-15 20:54:49
至于法比安说,这是很难比快math.sqrt
。原因是它使用CPython从C库中调用相应的函数。
from math import sqrt
到开方以后每次通话将不一定要看它的数学模块,从而节省了执行时间:
但是,您可以通过删除属性查找的开销,加快东西:
print sqrt(2)
这里是定时号码,从最快到最慢的(Python的2.6.5,Mac OS X的10.6.3):sqrt
比**0.5
更快:
[email protected] ~ % python -m timeit -s 'from math import sqrt; x = 2' 'sqrt(x)'
1000000 loops, best of 3: 0.207 usec per loop
[email protected] ~ % python -m timeit -s 'x = 2' 'x**0.5'
1000000 loops, best of 3: 0.226 usec per loop
[email protected] ~ % python -m timeit -s 'import math; x = 2' 'math.sqrt(x)'
1000000 loops, best of 3: 0.268 usec per loop
请注意,计时测试计算变量的平方根。他们不计算恒定像2**0.5
,因为2**0.5
是预 -calculated,在CPython的:
import dis
def f():
return 2**0.5
print dis.dis(f)
打印
2 0 LOAD_CONST 3 (1.4142135623730951)
3 RETURN_VALUE
在那里你看到不断浮动的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
和伪翻译到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
+1实际回答问题:) – 2012-09-26 06:10:01
在某些特殊情况下,你可以交易程序大小起泡速度。创建一个大型数组并存储每个平方根操作的预计算结果(使用输入值作为索引)。这是相当有限的,但你不会得到更快。
(这是怎么做到的)
如果这些值都是小整数,这可以工作。如果这些值是任意实数,则这不起作用。此外,这只适用于您希望看到相同的号码多次出现。即使在这样的情况下,我并不是计算输入中可能永远不会显示的数千个数的平方根,而是构建一个缓存并在第一次需要时计算平方根,然后使用缓存中的值。 – Jay 2015-05-08 20:18:12
用于计算正方形的Python代码片段。它首先做出初步猜测,如果猜测不够好,它会迭代,直到我们有一个好的猜测。
def gen_square_root_v1(number, epsilon):
#boundary condition check
if number == '1':
return 1
elif number <= 0:
print('this computes square root for positive numbers only')
else:
pass
prev_estimate = number/2
while True:
#each itearation, calculate a new estimate
new_estimate = (prev_estimate + number/prev_estimate)/2
#Alternatively can use if abs(new_estimate - prev_estimate) < epsilon:
#check the difference between square of new_estimate and number
if abs(new_estimate * new_estimate - number) < epsilon:
return prev_estimate
#if guess is not good enough, use it to make the next guess
prev_estimate = new_estimate
#call the function
print(gen_square_root_v1(16,1e-5))
sqrt()s只是很慢。你真的需要找到20k个不同的根,或者你可以使用查找表或缓存结果吗? – 2010-06-15 17:22:07