为什么2**100比数学.pow(2100)?

2024-09-28 03:23:41 发布

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

当讨论Exponentials in python x.**y vs math.pow(x, y)问题时, Alfe stated在python中没有好的理由使用math.pow来代替内置的**运算符。在

timeit shows that math.pow is slower than ** in all cases. What is math.pow() good for anyway? Has anybody an idea where it can be of any advantage then?

我们试图用一些timeit的论点来说服对方,他是目前为止的赢家;—)——至少下面的timeit结果似乎证实了math.pow is slower than ** in all cases。在

import timeit
print timeit.timeit("math.pow(2, 100)",setup='import math')
print timeit.timeit("2.0 ** 100.0")
print timeit.timeit("2 ** 100")
print timeit.timeit("2.01 ** 100.01")

输出:

^{pr2}$

ideone-shortcut

我们观察到的差异有没有简单的解释?


math.pow和{}的性能相差一个数量级。在

编辑:

  • 文字参数而不是标题中的变量
  • 明确指出差异大小的脚注

Tags: inimportismath差异allvsprint
1条回答
网友
1楼 · 发布于 2024-09-28 03:23:41

实际上,power操作符在示例中表现得很好的原因是Python在编译时很可能有folded the constant。在

import dis
dis.dis('3.0 ** 100')    
i = 100
dis.dis('3.0 ** i')

这将产生以下输出:

^{pr2}$

您可以在这里看到这个运行:http://ideone.com/5Ari8o

所以在本例中,您可以看到它实际上并没有对幂运算符与math.pow的性能进行公平的比较,因为结果已经被预先计算并缓存了。当您进行3.0 ** 100时,不执行任何计算,只返回结果。这比运行时执行的任何求幂运算都要快得多。这就是最终解释你的结果的原因。在

为了更公平地进行比较,您需要使用变量强制在运行时进行计算:

print timeit.timeit("3.0 ** i", setup='i=100')

我尝试在我的计算机上使用python 3.4.1对此进行快速基准测试:

import timeit
trials = 1000000
print("Integer exponent:")
print("pow(2, 100)")
print(timeit.timeit(stmt="pow(2, 100)", number=trials))
print("math.pow(2, 100)")
print(timeit.timeit(stmt="m_pow(2, 100)", setup='import math; m_pow=math.pow', number=trials))
print("2 ** 100")
print(timeit.timeit(stmt="2 ** i", setup='i=100', number=trials))
print("2.0 ** 100")
print(timeit.timeit(stmt="2.0 ** i", setup='i=100', number=trials))
print("Float exponent:")
print("pow(2.0, 100.0)")
print(timeit.timeit(stmt="pow(2.0, 100.0)", number=trials))
print("math.pow(2, 100.0)")
print(timeit.timeit(stmt="m_pow(2, 100.0)", setup='import math; m_pow=math.pow', number=trials))
print("2.0 ** 100.0")
print(timeit.timeit(stmt="2.0 ** i", setup='i=100.0', number=trials))
print("2.01 ** 100.01")
print(timeit.timeit(stmt="2.01 ** i", setup='i=100.01', number=trials))

结果:

Integer exponent:
pow(2, 100)
0.7596459520525322
math.pow(2, 100)
0.5203307256717318
2 ** 100
0.7334983742808263
2.0 ** 100
0.30665244505310607
Float exponent:
pow(2.0, 100.0)
0.26179656874310275
math.pow(2, 100.0)
0.34543158098034743
2.0 ** 100.0
0.1768205988074767
2.01 ** 100.01
0.18460920008178894

所以看起来,转换成float占用了相当多的执行时间。在

我还为math.pow添加了一个基准测试,注意这个函数与内置的pow有关更多信息,请参见这个:Difference between the built-in pow() and math.pow() for floats, in Python?

相关问题 更多 >

    热门问题