如何在不使用数学模块的情况下执行平方根?

2024-04-20 06:51:08 发布

您现在位置:Python中文网/ 问答频道 /正文


Tags: python
3条回答

正如Fabian所说,很难比math.sqrt快。原因是它用CPython从C库调用了相应的函数。

但是,您可以通过移除属性查找的开销来加快速度:

from math import sqrt

对sqrt的每个后续调用都将而不是必须在数学模块中查找它,这节省了执行时间:

print sqrt(2)

下面是从最快到最慢的计时数字(Python2.6.5,MacOSX10.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

注意,计时测试计算变量的平方根。它们不计算像2**0.5这样的常数,因为2**0.5是预先计算的,在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是一种方法,正如在另一个答案中提到的那样。

导入数学模块只发生一次,而且您可能不会比数学模块快多少。还有一个关于Which is faster in Python: x**.5 or math.sqrt(x)?的旧Stackoverflow问题。不清楚哪种方法更快。

也许可以看看NumPySciPy,不一定是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

相关问题 更多 >