为什么列表乘法这么快? [英] Why is list multiplication so fast?
问题描述
在创建列表时,我认为建议尽可能使用理解,因为它是最快的.但是你瞧.
When creating a list, I thought comprehension is recommended whenever possible as it is fastest. But lo and behold.
In [1]: %timeit -n1000 [0]*1000000
1000 loops, best of 3: 2.3 ms per loop
In [2]: %timeit -n1000 [0 for _ in range(1000000)]
1000 loops, best of 3: 27.1 ms per loop
In [3]: a = np.zeros(1000000, dtype=int)
In [4]: %timeit -n1000 a.tolist()
1000 loops, best of 3: 7.93 ms per loop
即使 numpy.ndarray.tolist
也跟不上乘法.这是为什么?
Even numpy.ndarray.tolist
can't keep up with multiplication. Why is that?
推荐答案
dis
模块对于比较前两种方法很有用.
The dis
module is useful for comparing the first two methods.
def list_mult():
return [0]*1000000
dis.dis(list_mult)
# 2 0 LOAD_CONST 1 (0)
# 3 BUILD_LIST 1
# 6 LOAD_CONST 2 (1000000)
# 9 BINARY_MULTIPLY
# 10 RETURN_VALUE
这里使用了 BINARY_MULTIPLY
指令.另一方面...
Here, the BINARY_MULTIPLY
instruction is used. On the other hand...
def list_range():
return [0 for _ in range(1000000)]
dis.dis(list_range)
# 2 0 BUILD_LIST 0
# 3 LOAD_GLOBAL 0 (range)
# 6 LOAD_CONST 1 (1000000)
# 9 CALL_FUNCTION 1
# 12 GET_ITER
# >> 13 FOR_ITER 12 (to 28)
# 16 STORE_FAST 0 (_)
# 19 LOAD_CONST 2 (0)
# 22 LIST_APPEND 2
# 25 JUMP_ABSOLUTE 13
# >> 28 RETURN_VALUE
此函数显式构造一个循环,然后在每次迭代中加载 0 并将其附加到工作列表中.这会慢很多.
This function explicitly constructs a loop, and then loads 0 and appends it to the working list in each iteration. This is going to be a lot slower.
需要注意的是,这两种构造方法并不等价,尤其是当列表中的值是可变的时.例如,[object()] * 10
会给你一个包含 10 个相同对象的列表,而 [object() for _ in range(10)]
会给你给你一个包含 10 个不同对象的列表.
It should be noted that these two construction methods are not equivalent, particularly when the value inside the list is mutable. For example, [object()] * 10
will give you a list of 10 of the same object, while [object() for _ in range(10)]
will give you a list of 10 distinct objects.
就 numpy
示例而言,此操作是 numpy
的最坏情况.构造和转换 numpy
数组有很多开销,因此矢量化操作可以很快(如注释中所述).
Regarding the numpy
example, this operation is kind of the worst-case for numpy
. There is a lot of overhead in constructing and converting numpy
arrays so that the vectorized operations can be fast (as noted in the comments).
这篇关于为什么列表乘法这么快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!