我想知道是x**2还是x*x更快

def sqr(x):
    for i in range (20):
        x = x**2
    return x
def sqr_(x):
    for i in range (20):
        x = x*x
    return x

当我计时时,我得到的是:

The time it takes for x**2: 101230500
The time it takes for x*x: 201469200

我已经试过很多次了,它们要么相等,要么x**2比x*x快.但是x*x永远不会比x**2快.

所以我掩饰了代码:

对于x**2:

  5          12 LOAD_FAST                0 (x)
             14 LOAD_CONST               2 (2)
             16 BINARY_POWER
             18 STORE_FAST               0 (x)
             20 JUMP_ABSOLUTE            8

对于x*x:

  9          12 LOAD_FAST                0 (x)
             14 LOAD_FAST                0 (x)
             16 BINARY_MULTIPLY
             18 STORE_FAST               0 (x)
             20 JUMP_ABSOLUTE            8

它是关于load_const比load_fast稍微快一点吗?

LOAD_CONST:获取co_CONST的索引1处的文本值并将其推送

LOAD_FAST是通过索引访问数组中的值

或者二进制幂比二进制乘快(我实际上不知道二进制幂算法)?

推荐答案

For small integers, 100 is significantly faster than 101因为CPython在内部进行了大量运算来计算a**b.实际上,在我的机器上,x*x的速度是4倍(处理器i5-9600KF,Windows上的CPython 3.8.1).也就是说,在代码中,数字增长非常快,Python整数是无界的.事实上,每次求幂都会导致二进制表示的大小增加一倍.指数相乘,计算出x**(2*2*2*...*2) = x**(2**20) = x**1048576.对于大x=2,这个数字需要128千兆位内存,而对于x=100,则需要850千兆位内存.这相当大.循环的每一次迭代都受到内存中如此庞大的数字计算的限制.因此,for large numbers, 100 and 101 are as fast是因为这两种情况下都进行了相同的内部计算,与计算大整数相比,CPython解释器的开销变得微不足道.


引擎盖下

在内部,CPython似乎使用ternary_op9111db393afaecdb04cc4093de/Objects/abstract.c#L1158" rel="nofollow noreferrer">_PyNumber_PowerNoMod调用ternary_op9111db393afaecdb04cc4093de/Objects/abstract.c#L1152" rel="nofollow noreferrer">PyNumber_Power调用ternary_op,使用PyNumber_Multiply调用binary_op1.注意,CPython没有优化到计算x**2:内部CPython compute pow(x, 2, None)是计算模幂的函数(尽管调用pow的方式效率稍低,因为CPython必须判断pow是否被覆盖).这个模幂函数要昂贵得多,因为与x * x相比,它是generic function.

最后,在您的例子中似乎调用了long_mullong_pow(注意long_pow在内部调用long_mul,所以long_pow实际上需要计算更多指令).

对于较大的数字,CPython使用Karatsuba multiplication(参见:k_mul).

请注意,CPython实际上在这两种情况下都非常慢,因为它需要几纳秒(至少在我的机器上是这样),只需将两个整数相乘就可以执行几十次判断和许多函数调用.对于主流x86-64处理器上的64位整数,这可以在一个周期内完成.大整数不能由主流处理器自然计算,需要更昂贵的计算.

Python相关问答推荐

从收件箱中的列中删除html格式

使可滚动框架在tkinter环境中看起来自然

C#使用程序从Python中执行Exec文件

当从Docker的--env-file参数读取Python中的环境变量时,每个\n都会添加一个\'.如何没有额外的?

cv2.matchTemplate函数匹配失败

在pandas/python中计数嵌套类别

pysnmp—lextudio使用next()和getCmd()生成器导致TypeError:tuple对象不是迭代器''

如何按row_id/row_number过滤数据帧

在用于Python的Bokeh包中设置按钮的样式

应用指定的规则构建数组

如何用FFT确定频变幅值

如何设置nan值为numpy数组多条件

某些值的数值幂和**之间的差异

奇怪的Base64 Python解码

将时间序列附加到数据帧

如何使用count()获取特定日期之间的项目

运行从Airflow包导入的python文件,需要airflow实例?

Python键盘模块不会立即检测到按键

给定y的误差时,线性回归系数的计算误差

Pandas:根据系列词典中的值筛选行