На маленьком проекте подмена времени стоит 1406,7 микросекунды против 1,5, на большом — 40 971,3 против тех же 1,5
Адам Джонсон, автор
Стенд простой: генерируются пустые модули по 25 атрибутов, каждый десятый держит ссылки на
🔘 259 модулей, то есть почти голый интерпретатор: 1406,7 мкс против 1,5 мкс, разница в 940 раз;
🔘 1259 модулей, размер небольшого проекта на Django: разница в 2490 раз;
🔘 16 259 модулей, крупный проект с обвесом зависимостей: 40 971,3 мкс против неизменных 1,5 мкс, разница в 27 300 раз;
🔘 время
🔘 в наборе из 2000 тестов с подменой времени это 82 секунды чистой замены ссылок против 3 миллисекунд;
🔘 причина в том, что
У обхода есть и содержательная плата, помимо скорости: он не находит ссылки в атрибутах классов, значениях по умолчанию, замыканиях и C-расширениях, и они продолжают отдавать настоящее время. Плюс подставленные объекты видны по типу,
Автор оговаривает, что модули в стенде синтетические, это
Полная статья: https://adamj.eu/tech/2026/08/03/python-time-machine-o1-freezegun-on/
@zen_of_python
Адам Джонсон, автор
time-machine, замерил 3 августа, как две библиотеки подмены текущего времени ведут себя с ростом проекта. Прошлый такой замер он делал в 2021 году и получил разницу в 100–200 раз, теперь захотел показать не отношение, а саму зависимость от размера кодовой базы.Стенд простой: генерируются пустые модули по 25 атрибутов, каждый десятый держит ссылки на
date, datetime и time, как будто их импортировали по имени. Замеряется цикл включения и выключения подмены. Python 3.15, MacBook на M1, freezegun 1.5.5 и time-machine 3.3.0.freezegun укладывается в прямую: около 1,4 мс постоянных расходов плюс 2,5 мкс на каждый модуль;freeze_time.start() обходит весь sys.modules и подменяет каждую найденную ссылку на настоящие функции; даже при попадании в кэш приходится перечислить и захешировать имена атрибутов всех модулей.У обхода есть и содержательная плата, помимо скорости: он не находит ссылки в атрибутах классов, значениях по умолчанию, замыканиях и C-расширениях, и они продолжают отдавать настоящее время. Плюс подставленные объекты видны по типу,
datetime.__name__ внутри подмены становится FakeDatetime, и код, который смотрит на типы, может повести себя иначе.time-machine вместо обхода переписывает указатель ml_meth в структуре PyMethodDef у встроенных функций, читающих часы. Таких функций десять, и это ровно десять записей в память независимо от размера проекта.Автор оговаривает, что модули в стенде синтетические, это
types.ModuleType, положенные прямо в sys.modules, а не настоящие импорты, и что замеряется только цикл подмены, из нескольких прогонов берётся минимальное время.Полная статья: https://adamj.eu/tech/2026/08/03/python-time-machine-o1-freezegun-on/
@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2