Просто напоминание о том, как работают целые числа Python: если вы выделяете список, говоря
a = [0] * K
, вам нужна память для списка (sizeof(PyListObject) + K * sizeof(PyObject*)
) и память для одного целочисленного объекта 0
,Пока числа в списке остаются ниже магического числа V
, которое Python использует для кэширования, у вас все в порядке, потому что они являются общими, то есть любое имя, которое указывает на число n < V
, указывает на точно такой же объект.Вы можете найти это значение с помощью следующего фрагмента:
>>> i = 0
>>> j = 0
>>> while i is j:
... i += 1
... j += 1
>>> i # on my system!
257
Это означает, что, как только число превысит это число, вам понадобится память sizeof(PyListObject) + K * sizeof(PyObject*) + d * sizeof(PyIntObject)
, где d < K
- это числоцелые числа выше V (== 256)
.В 64-битной системе sizeof(PyIntObject) == 24
и sizeof(PyObject*) == 8
, то есть наихудшее потребление памяти составляет 3 200 000 000 байтов.
При numpy.ndarray
или array.array
потребление памяти остается постоянным после инициализации, но вы платите за объекты-оболочки, которые создаются прозрачно, как сказал Томас Воутерс.Вероятно, вам следует подумать о преобразовании кода обновления (который получает доступ и увеличивает позиции в массиве) в код на языке C, используя Cython или scipy.weave
.