Самая длинная часть в вашем фрагменте кода занимает распределение (в моей системе 0,56 с), а не освобождение (в моей системе 0,07 с).
import numpy as np, time, gc
print("1")
start = time.time()
#gc.disable()
data_list = [np.zeros((4, 408), dtype=complex) for _ in range(350000)]
mid = time.time()
#gc.enable()
print("2")
data_list = [] # "this takes fairly long time" (doesn't for me)
end = time.time()
print("3")
print(mid-start, end-mid)
Моя догадка равна было , так как из-за больших элементов сборщик мусора запускается много раз во время выделения l oop (не проверял) , но это не так; даже отключение сборки мусора вокруг выделения не ускоряет код в моей системе .
Создание единого массива с
data = np.zeros((350000, 4, 408), dtype=complex)
data = []
незамедлительно, так как это одна большая память Объект выделен и освобожден в одном go. Конечно, это не объект list
, поэтому поведение не совсем то же самое.
Если ваш код занимает много времени при освобождении, возможно, проблема в перегрузке основной памяти (т. Е. В пейджинге). 350000x4x408 составляет около 500 миллионов, и это число комплексных чисел двойной точности будет принимать в массиве numpy около 9 ГБ (и намного больше, чем complex
Python объектов).
Если вы этого не сделаете если у вас есть такой объем свободной оперативной памяти, то управление ею с использованием виртуальной памяти будет проблемой, и, действительно, наблюдаемым симптомом может быть то, что после завершения обработки требуется много времени, чтобы «вернуться назад» ко всем материалам, которые были выделены для освободите место для данных.
Если это так, то даже хранение всех ваших данных в одном блоке памяти не сильно ускорится (время, потраченное на восстановление отброшенных 9 ГБ, а не освобождение памяти) само по себе).
В системах Windows ущерб производительности системы может быть даже "постоянным" в случае входа в режим tra sh: другими словами, система может быть не в состоянии восстановить нормальную скорость до следующей перезагрузки. Это происходило много лет go (Windows XP), и я не использую Windows регулярно ... возможно, последние версии устранили проблему.
ОБНОВЛЕНИЕ
Как Вы протестировали скрипт, и все же освобождение занимает 2 минуты. Думаю, объяснение может быть в дистрибутиве python или numpy. Чтобы проверить, в чем проблема, вы можете заменить
np.zeros((4, 408), dtype=complex)
на
array.array("d", [0.0]) * (2*4*408))
, чтобы выделить тот же объем памяти, используя только стандартные Python объекты; если проблема остается, то проблема в ядре python, в противном случае она находится в numpy. В обоих случаях я бы отправил отчет об ошибке ... может быть, это известная проблема на windows, и ответ будет "wontfix", но кажется странным, поскольку освобождение в моей системе Linux занимает менее 1se c и моя система, похоже, не в 120 раз мощнее вашей.