Я пытался создать пример, в котором предварительное выделение массива numpy выполняется быстрее, чем использование .append в списке, но в итоге доказал обратное.

import numpy as np
import time

t = time.time()
emptyList   = []
for i in range(int(1e8)):
    emptyList.append(1)
print("Append: ", time.time() - t)

t = time.time()
emptyList   = np.empty(int(1e8))
for i in range(int(1e8)):
    emptyList[i] = 1
print("Preallocate: ", time.time() - t)

Что дает следующий результат:

Append:  12.733097314834595
Preallocate:  19.008652925491333

Я очень смущен тем, почему в этом случае добавление к списку происходит быстрее. Я также пробовал везде использовать случайные числа вместо «1», но получил тот же результат.

0
Cyrano Chatziantoniou 15 Июн 2021 в 00:39

2 ответа

Лучший ответ

Обратите внимание, что вы не используете один и тот же класс в обоих примерах. Вы сравниваете append для встроенного типа Python list с назначением - не списку, а для выделения и назначения массиву NumPy.

Я ожидал бы, что они будут намного ближе, но проблема не в этом: у вас есть два элемента: выделение и назначение.

Когда я запускаю ваш код, как указано, я получаю

Append:       16.296499013900757
Preallocate:  16.835283517837524

Когда я изменяю второй цикл, чтобы устранить накладные расходы NumPy:

emptyList   = [0] * (int(1e8))

Результат:

Append:       23.76796054840088
Preallocate:  11.050438404083252
2
Prune 14 Июн 2021 в 21:47

Это потому, что списки Python на самом деле не являются связанными списками; они реализованы в виде массивов: https : //docs.python.org/3/faq/design.html#how-are-lists-implemented-in-cpython

Когда элементы добавляются или вставляются, размер массива ссылок изменяется. Применяется некоторая смекалка, чтобы улучшить производительность многократного добавления элементов; когда массив должен быть увеличен, выделяется дополнительное пространство, поэтому в следующие несколько раз фактическое изменение размера не потребуется.

Они умнее, чем просто увеличивать каждый раз, когда запрашивается одно добавление, подобно тому, как TCP работает с мультипликативным увеличением.

Другое чтение: https://www.geeksforgeeks.org/internal-working-of -list-in-python /

Как реализован список Python?

3
Tommy 14 Июн 2021 в 21:42