Exponentials in python x.**y vs math.pow(x, y)
使用math.pow或**运算符哪个更有效? 我什么时候应该使用另一个?
到目前为止,我知道
函数
1 2 3 4 5 | import math print math.pow(10, 2) print 10. ** 2 |
使用动力运算符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | >>> dis.dis('7. ** i') 1 0 LOAD_CONST 0 (7.0) 3 LOAD_NAME 0 (i) 6 BINARY_POWER 7 RETURN_VALUE >>> dis.dis('pow(7., i)') 1 0 LOAD_NAME 0 (pow) 3 LOAD_CONST 0 (7.0) 6 LOAD_NAME 1 (i) 9 CALL_FUNCTION 2 (2 positional, 0 keyword pair) 12 RETURN_VALUE >>> dis.dis('math.pow(7, i)') 1 0 LOAD_NAME 0 (math) 3 LOAD_ATTR 1 (pow) 6 LOAD_CONST 0 (7) 9 LOAD_NAME 2 (i) 12 CALL_FUNCTION 2 (2 positional, 0 keyword pair) 15 RETURN_VALUE |
请注意,这里我使用变量
现在,实际上,这种差异并不重要,正如您在计时时可以看到的那样:
1 2 3 4 5 6 7 | >>> from timeit import timeit >>> timeit('7. ** i', setup='i = 5') 0.2894785532627111 >>> timeit('pow(7., i)', setup='i = 5') 0.41218495570683444 >>> timeit('math.pow(7, i)', setup='import math; i = 5') 0.5655053168791255 |
因此,尽管
Alfe在上述评论中提出了一个很好的问题:
timeit shows thatmath.pow is slower than** in all cases. What ismath.pow() good for anyway? Has anybody an idea where it can be of any advantage then?
我们来看一个示例:我们有两个数字
-
我们可以将至少一个参数转换为浮点数,然后执行
i ** j 。 -
我们可以执行
i ** j 并将结果转换为浮点数(当i 或j 为浮点数时,将自动使用浮点指数,因此结果相同)。 -
我们可以使用
math.pow 。
因此,让我们测试一下:
1 2 3 4 5 6 7 8 | >>> timeit('float(i) ** j', setup='i, j = 7, 5') 0.7610865891750791 >>> timeit('i ** float(j)', setup='i, j = 7, 5') 0.7930400942188385 >>> timeit('float(i ** j)', setup='i, j = 7, 5') 0.8946636625872202 >>> timeit('math.pow(i, j)', setup='import math; i, j = 7, 5') 0.5699394063529439 |
如您所见,
此外,可能需要注意,通过为自定义类型实现特殊的
仅针对协议:
因此,如果要通过幂计算余数,请使用内置函数。
1 2 3 4 5 6 7 | import math base = 13 exp = 100 mod = 2 print math.pow(base, exp) % mod print pow(base, exp, mod) |
运行此命令时,我在第一种情况下得到的
为了公平起见,我们必须说
1 2 3 | import timeit print timeit.timeit("math.pow(2, 100)",setup='import math') print timeit.timeit("pow(2, 100)") |
这是我得到的输出:
1 2 | 0.240936803195 1.4775809183 |
一些在线示例
-
http://ideone.com/qaDWRd(
math.pow 的余数错误) -
http://ideone.com/g7J9Un(在int值上使用
pow 时性能较低) -
http://ideone.com/KnEtXj(浮点值
pow 时性能略低)
好吧,它们确实是用于不同的任务。
当您需要整数运算时,请使用
并使用
有关
1 | 10.*10. |
会更快
1 | 10.**2 |
一次操作(使用
pow()函数将允许您添加第三个参数作为模数。
例如:我最近在执行操作时遇到内存错误
2**23375247598357347582 % 23375247598357347583
相反,我做了:
pow(2, 23375247598357347582, 23375247598357347583)
这仅需几毫秒即可返回,而不是简单的指数所花费的大量时间和内存。 因此,当处理大数和并行模数时,pow()效率更高,但是当处理小数而无模数时,**效率更高。