Все самое полезное для питониста в одном канале.
Учиться у нас: clc.to/6e5Csg
Для обратной связи: @proglibrary_feeedback_bot
По рекламе: @tproger_sales_bot
РКН: https://gosuslugi.ru/snet/67b885cbd501cf3b2cdb5b36
Post #7273
3.61K
💡 Как часто Python делает аллокации
Короткий ответ — очень часто.
🐁 Каждое число — объект
В CPython каждое целое число — это объект
Если бы каждое число выделялось через
Но Python применяет несколько хитрых оптимизаций.
Добавим вывод в функцию аллокации чисел и запустим код:
Результат:
Кажется, создаётся новый объект на каждой итерации.
Но без
Теперь:
То есть новые объекты создаются редко — большинство просто переиспользуются.
🐁 Как это работает
Функция сложения в CPython выглядит примерно так:
После освобождения объект возвращается обратно во freelist, а не в систему.
Результат эксперимента:
99% чисел просто переиспользуются!
🐁 Малые числа предсозданы
Для диапазона
Такие числа никогда не аллоцируются — просто возвращаются из таблицы. Это ещё одна оптимизация CPython.
🐁 Как Python управляет памятью
CPython использует собственный пуловый аллокатор (
Выделение из пула выполняется почти мгновенно, без системных вызовов
Физическая память подгружается лениво — по мере использования.
🐁 На практике это значит: Python «аллoцирует» очень часто, но реальных системных аллокаций почти нет.
🐸 Библиотека питониста
#буст
Короткий ответ — очень часто.
🐁 Каждое число — объект
В CPython каждое целое число — это объект
PyLongObject*, хранящийся в куче. Даже операция i + 1 создаёт новый объект.Если бы каждое число выделялось через
malloc/free, арифметика была бы в сотни раз медленнее, чем машинная инструкция ADD.Но Python применяет несколько хитрых оптимизаций.
Добавим вывод в функцию аллокации чисел и запустим код:
for i in range(0, 100_000):
print(i + 1)
Результат:
Allocating number object 100904 times
Кажется, создаётся новый объект на каждой итерации.
Но без
print():for i in range(0, 100_000):
a = i + 1
Теперь:
Allocating number object 905 times
То есть новые объекты создаются редко — большинство просто переиспользуются.
🐁 Как это работает
Функция сложения в CPython выглядит примерно так:
static PyLongObject *
long_add(PyLongObject *a, PyLongObject *b)
{
stwodigits z = medium_value(a) + medium_value(b);
return _PyLong_FromSTwoDigits(z);
}
_PyLong_FromSTwoDigits решает, брать ли объект из freelist (списка свободных объектов) или выделять новый:PyLongObject *v = _Py_FREELIST_POP(PyLongObject, ints);
if (v == NULL) v = PyObject_Malloc(sizeof(PyLongObject));
После освобождения объект возвращается обратно во freelist, а не в систему.
Результат эксперимента:
102 ALLOCATING
99193 REUSING
99% чисел просто переиспользуются!
🐁 Малые числа предсозданы
Для диапазона
-5..1024 объекты создаются заранее:PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
Такие числа никогда не аллоцируются — просто возвращаются из таблицы. Это ещё одна оптимизация CPython.
🐁 Как Python управляет памятью
CPython использует собственный пуловый аллокатор (
pymalloc). Память разбита на пулы фиксированного размера (по 256 КБ).Выделение из пула выполняется почти мгновенно, без системных вызовов
malloc() или mmap().Физическая память подгружается лениво — по мере использования.
🐁 На практике это значит: Python «аллoцирует» очень часто, но реальных системных аллокаций почти нет.
🐸 Библиотека питониста
#буст
- 👍 18
- ❤ 9
- 💯 1











