使用指数**比math.sqrt效率低0.5?

时间:2011-07-09 21:30:40

标签: python exponentiation

引自“Python Programming: An Introduction to Computer Science

  

我们可以采取平方根   使用指数**。运用   math.sqrt更有效率。

“有点”,但在多大程度上,以及如何?

5 个答案:

答案 0 :(得分:16)

从理论上讲,hammar's answerduffymo's answer是很好的猜测。但实际上,在我的机器上, 更高效:

>>> import timeit
>>> timeit.timeit(stmt='[n ** 0.5 for n in range(100)]', setup='import math', number=10000)
0.15518403053283691
>>> timeit.timeit(stmt='[math.sqrt(n) for n in range(100)]', setup='import math', number=10000)
0.17707490921020508

部分问题是.操作。如果将sqrt直接导入命名空间,则会略有改进。

>>> timeit.timeit(stmt='[sqrt(n) for n in range(100)]', setup='from math import sqrt', number=10000)
0.15312695503234863

关键词:轻微

进一步测试表明,随着数量变大,使用sqrt带来的好处会增加。但仍然不是很多!

>>> timeit.timeit(stmt='[n ** 0.5 for n in range(1000000)]', setup='import math', number=1)
0.18888211250305176
>>> timeit.timeit(stmt='[math.sqrt(n) for n in range(1000000)]', setup='import math', number=1)
0.18425297737121582
>>> timeit.timeit(stmt='[sqrt(n) for n in range(1000000)]', setup='from math import sqrt', number=1)
0.1571958065032959

答案 1 :(得分:11)

无需猜测实现,我们可以阅读代码!

math.sqrt是标准C库中sqrt的精简包装:请参阅mathmodule.c, line 956

**运算符具有多个实现,具体取决于参数的类型,但在浮点指数的情况下,它最终从标准C库调度到pow(请参阅{{ 3}})。

现代CPU通常具有特殊的平方根指令,一般取幂例程不使用(例如,比较和对比glibc中floatobject.c line 783pow的实现,例如x86-64)。但是一旦添加了所有的解释器开销(字节码,类型检查,方法调度等),原始速度的差异并不重要,并且可以由诸如是否直接调用sqrt或通过math模块查找(如其他答案中的时间所示)。

答案 2 :(得分:1)

**必须支持任何指数,math.sqrt知道它总是0.5。因此math.sqrt可以使用更专业(因此可能更有效)的算法。

答案 3 :(得分:1)

我的猜测是math.sqrt使用Newton's method,它以二次方式收敛,而取幂使用其他更慢的东西。

答案 4 :(得分:1)

这是一种略有不同的方法。我们想要一个比平方根大的int。两种方式(对于平方数字不同意,但没关系):

>>>timeit.timeit(stmt='[int(n**0.5)+1 for n in range(1000000)]', setup='', number=1)  
0.481772899628  
>>>timeit.timeit(stmt='[ceil(sqrt(n)) for n in range(1000000)]', setup='from math import sqrt, ceil', number=1)  
0.293844938278  
>>>timeit.timeit(stmt='[int(ceil(sqrt(n))) for n in range(1000000)]', setup='from math import sqrt, ceil', number=1)  
0.511347055435

所以数学函数更快......直到你将float转换为int。 (我需要对值进行大量比较,虽然我没有测试过,但比较整数应该比比较浮点数便宜。)

但是,嘿,它是 Python 。您可以通过太多的抽象来尝试以这种粒度级别优化性能。