gpt4 book ai didi

python - python 中 n 项到列表的追加和 [0]*n 的不同追加?

转载 作者:行者123 更新时间:2023-11-30 23:30:16 24 4
gpt4 key购买 nike

我有两个相同的代码
代码1

>>> a=[0]*60000000

代码2

>>> a=[]
>>> for i in range(0,60000000):
a.append(0)

在我的电脑中,Code1 所需时间是 1 秒,但 Code2 需要 480 秒!!
为什么 ?有什么不同?

最佳答案

(在下文中,我假设您使用的是 Python 3;在 Python 2 中,情况类似,但我们必须讨论由于范围而导致的内存分配成本。)

您的第二个程序花费时间在 Python 字节码中运行。让我们使用 dis 来反汇编它模块:

>>> import dis
>>> dis.dis('a=[]\nfor i in range(0,60000000):\n a.append(0)')
1 0 BUILD_LIST 0
3 STORE_NAME 0 (a)

2 6 SETUP_LOOP 36 (to 45)
9 LOAD_NAME 1 (range)
12 LOAD_CONST 0 (0)
15 LOAD_CONST 1 (60000000)
18 CALL_FUNCTION 2 (2 positional, 0 keyword pair)
21 GET_ITER
>> 22 FOR_ITER 19 (to 44)
25 STORE_NAME 2 (i)

3 28 LOAD_NAME 0 (a)
31 LOAD_ATTR 3 (append)
34 LOAD_CONST 0 (0)
37 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
40 POP_TOP
41 JUMP_ABSOLUTE 22
>> 44 POP_BLOCK
>> 45 LOAD_CONST 2 (None)
48 RETURN_VALUE

循环从字节22运行到字节41,每次循环时,Python都必须解码并执行七个字节码指令,并调用一个函数(函数是a.append) 。这相当于 4.2 亿字节代码指令和 6000 万次函数调用。

而您的第一个程序花费时间在 native 代码中运行:

>>> dis.dis('a = [0] * 60000000')
1 0 LOAD_CONST 0 (0)
3 BUILD_LIST 1
6 LOAD_CONST 1 (60000000)
9 BINARY_MULTIPLY
10 STORE_NAME 0 (a)
13 LOAD_CONST 2 (None)
16 RETURN_VALUE

可以看到,不仅没有循环,也没有函数调用。所有工作都发生在 BINARY_MULTIPLY 指令的“幕后”,该指令分派(dispatch)到 list_multiply in listobject.c ,并且由于列表 [0] 仅包含一个元素,因此结果是在第 529-536 行的紧密循环中构造的:

if (Py_SIZE(a) == 1) {
elem = a->ob_item[0];
for (i = 0; i < n; i++) {
items[i] = elem;
Py_INCREF(elem);
}
return (PyObject *) np;
}

关于python - python 中 n 项到列表的追加和 [0]*n 的不同追加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20722405/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com