Упс, это плохой случай оптимизации для списков целых чисел. Проблема в том, что это начинается как список целых:
bin2 = [0] * L
Это внутренне хранится как массив целых чисел. Обычно он намного компактнее, хотя в этом случае он ничего не меняет - потому что на CPython это список, содержащий L
копии одного и того же объекта 0
.
Но проблема в том, что довольно скоро мы сохраняем long
в списке. На данный момент нам нужно превратить весь список в общий вид, который может хранить что угодно. Но! Проблема в том, что мы видим 100 миллионов нулей, и поэтому мы создаем 100 миллионов 0
объектов. Это мгновенно создает нехватку памяти в 3 ГБ, в дополнение к 800 МБ для самого списка.
Мы можем проверить, что проблема не возникает, если мы инициализируем список следующим образом, так что он действительно содержит 100 миллионов раз один и тот же объект:
bin2 = [0L] * L # Python 2.x
bin2[0] = 1
Тем не менее, в вашем примере вам не нужно, чтобы список содержал 100 миллионов элементов. Вы можете инициализировать его как:
bin2 = [1]
и используйте bin2.append()
. Это позволяет программе запускаться намного быстрее и без большого использования памяти в начале.
Обратите внимание, что PyPy3 по-прежнему использует больше памяти, чем CPython3.