tgoop.com/pyproglib/7050
Create:
Last Update:
Last Update:
Как избавиться от deepcopy и ускорить код в несколько разcopy.deepcopy()
удобно использовать, когда нужно получить полностью независимую копию сложного объекта.
Но за удобство приходится платить: функция обходит всю структуру объекта, вызывает __deepcopy__
, следит за циклическими ссылками и выделяет память под каждый элемент графа.
🤔 На практике это легко превращается в проблему. Пример из жизни — копирование состояния агента (≈1000 объектов) занимало 25% времени работы программы.
— обходит всю вложенную структуру
— вызывает Python-уровневый код (__deepcopy__
)
— использует memo-словарь для учёта общих ссылок
— аллоцирует память под каждый объект
В простом бенчмарке:
shallow copy → 1x
deepcopy → ~660x медленнее
pickle / json → ~100–500x медленнее
Если нужно изменить только один атрибут — проще создать новый экземпляр, передав поля явно, чем делать
deepcopy
+ модификацию:# вместо
m2 = deepcopy(m1); m2.bar = 5
# лучше
m2 = Model(bar=5, foo=m1.foo, ...)
В Pydantic-AI ушли от:
messages = deepcopy(self._state.message_history)
к:
messages = list(self._state.message_history)
last = deepcopy(messages[-1])
messages[-1] = last
→ в итоге 180× быстрее
Строки, числа, кортежи — и так безопасны. Не создавайте дубликаты ради дубликатов.
Вместо полной копии состояния — сохраните разницу (diff) или применяйте изменения лениво — только при первом реальном изменении.
Иногда быстрее склонировать структуру через
json.dumps/loads
или pickle
. Но подходит только для чистых данных (без сокетов, файлов и т.п.)— NumPy:
arr.copy()
— копирует чистый буфер памяти— pandas:
.copy()
/ .loc[:]
— быстрее, чем deepcopy
DataFrame—
deepcopy
— мощь → но крайне дорогая— Используйте
deepcopy
только если реально нужен полный независимый клон— Во всех остальных случаях: поверхностная копия + модификация → намного быстрее
#буст