简体   繁体   English

为什么切片比“手动”分配快得多?

[英]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]

  • load rot_arr , i , d , a_length and a加载rot_arrida_lengtha
  • call i.__sub__() and create intermediate object调用i.__sub__()并创建中间对象
  • call intermed.__mod__() and create intermediate object调用intermed.__mod__()并创建中间对象
  • call rot_arr.__setitem__ , decrementing and potentially freeing existing obj调用rot_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM