python math函数pow_python中的指数x.*y vs math.pow(x,y)

使用power运算符**将更快,因为它没有函数调用的开销。如果反汇编Python代码,可以看到这一点:>>> 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

注意,我在这里使用变量i作为指数,因为像7. ** 5这样的常量表达式实际上是在编译时计算的。

现在,在实践中,这种差异并没有那么重要,正如你在计时时所看到的:>>> 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

所以,虽然pow和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?

与内置的pow和幂运算符**的最大区别在于它始终使用浮点语义。因此,如果出于某种原因,您想确保返回的结果是float,那么math.pow将确保此属性。

举个例子:我们有两个数字,i和j,不知道它们是浮点数还是整数。但是我们想要一个i^j的浮点结果。我们有什么选择?我们至少可以将其中一个参数转换为浮点,然后执行i ** j。

我们可以做i ** j并将结果转换为浮点(当i或j是浮点时,会自动使用浮点指数,因此结果是相同的)。

我们可以使用math.pow。

那么,让我们来测试一下:>>> 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

如您所见,math.pow实际上更快!如果你仔细想想,函数调用的开销现在也没有了,因为在所有其他选择中,我们都必须调用float()。

此外,值得注意的是,**和pow的行为可以通过为自定义类型实现特殊的__pow__(和__rpow__)方法来重写。因此,如果您不想这样做(无论出于什么原因),那么使用math.pow就不会这样做。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值