为什么.append()比在预先分配的数组中设置值慢?

2024-04-25 00:35:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试加速我的部分代码,其中涉及循环和设置一个大型2D数组中的值。其中一个建议是,我尝试预先分配数组,而不是使用.append(),但有人指出,在Python中.append()是一个摊余的O(1)操作。在

但是,当我使用以下代码进行测试时:

import time

x = list()
z = list()
t1 = time.time()
for i in range(10000):
    z.append([])
    for j in range(10000):
        z[i].append(0)

t1 = time.time()
for i in range(10000):
    x.append([])
    for j in range(10000):
        x[i].append(1)
print(time.time()-t1)

t1 = time.time()
for i in range(10000):
    for j in range(10000):
        z[i][j] = 1
print(time.time()-t1)

我认为预先分配的数组比未预先分配的数组少3-4秒(大约17秒,而不是21秒)。这段代码中是什么导致基于.append()的函数比替换预先分配的数组中的值花费更长的时间?在


Tags: 函数代码inimportfortimerange数组
2条回答

考虑以下因素:

from dis import dis

def f1():
 x = []
 for i in range(10000):
  x.append([])
  for j in range(10000):
   x[i].append(0)
 return x

dis(f1)

  2           0 BUILD_LIST               0
              3 STORE_FAST               0 (x)

  3           6 SETUP_LOOP              73 (to 82)
              9 LOAD_GLOBAL              0 (range)
             12 LOAD_CONST               1 (10000)
             15 CALL_FUNCTION            1
             18 GET_ITER
        >>   19 FOR_ITER                59 (to 81)
             22 STORE_FAST               1 (i)

  4          25 LOAD_FAST                0 (x)
             28 LOAD_ATTR                1 (append)
             31 BUILD_LIST               0
             34 CALL_FUNCTION            1
             37 POP_TOP

  5          38 SETUP_LOOP              37 (to 78)
             41 LOAD_GLOBAL              0 (range)
             44 LOAD_CONST               1 (10000)
             47 CALL_FUNCTION            1
             50 GET_ITER
        >>   51 FOR_ITER                23 (to 77)
             54 STORE_FAST               2 (j)

  6          57 LOAD_FAST                0 (x)
             60 LOAD_FAST                1 (i)
             63 BINARY_SUBSCR
             64 LOAD_ATTR                1 (append)
             67 LOAD_CONST               2 (0)
             70 CALL_FUNCTION            1
             73 POP_TOP
             74 JUMP_ABSOLUTE           51
        >>   77 POP_BLOCK
        >>   78 JUMP_ABSOLUTE           19
        >>   81 POP_BLOCK

  7     >>   82 LOAD_FAST                0 (x)
             85 RETURN_VALUE

与之相比:

^{pr2}$

你处理事情的方式会有很大的不同。在

.append()会导致python分配更多内存,这需要时间。通过使用按分配的结构,可以节省执行所有单独分配的时间。在

相关问题 更多 >