[英]Why is slicing much faster than "manual" assignment?
I was working on an array rotation algorithm, where you rotate an array left by d
steps of rotation.我正在研究一种数组旋转算法,在该算法中,您将数组旋转
d
步。
I figured that slicing was a high level abstraction that would be much slower in reality than manually assigning each value in the array to a new location in the rotated array.我认为切片是一种高级抽象,实际上比手动将数组中的每个值分配给旋转数组中的新位置要慢得多。
It turns out slicing is almost 40 times faster.事实证明,切片速度快了近 40 倍。 Why is that?
这是为什么?
Here is the code for comparison:这是用于比较的代码:
def rot_left_manual(a, d):
a_length = len(a)
rot_arr = [0] * a_length
for i in range(a_length):
rot_arr[(i-d) % a_length] = a[i]
return rot_arr
def rot_left_slice(a, d):
i = d % len(a)
b = a[i:]
b += (a[:i])
return b
I'm using %timeit
in Jupyter notebooks to time function speed我在 Jupyter 笔记本中使用
%timeit
来计时功能速度
Python's binary operations are relatively expensive. Python 的二进制操作相对昂贵。 Looking at
rot_arr[(id) % a_length] = a[i]
for every execution of the loop在每次执行循环时
rot_arr[(id) % a_length] = a[i]
rot_arr
, i
, d
, a_length
and a
rot_arr
、 i
、 d
、 a_length
和a
i.__sub__()
and create intermediate objecti.__sub__()
并创建中间对象intermed.__mod__()
and create intermediate objectintermed.__mod__()
并创建中间对象rot_arr.__setitem__
, decrementing and potentially freeing existing objrot_arr.__setitem__
,递减并可能释放现有的 obj With slicing, almost all of the work is done in the list's slice method (implemented in C) which can optimize most of the moves with many fewer calculations and avoiding the expense of looking up or creating all of those python objects.通过切片,几乎所有的工作都在列表的切片方法(用 C 实现)中完成,它可以用更少的计算优化大部分移动,并避免查找或创建所有这些 Python 对象的费用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.