Разработчик выяснил, что 29% процессорного времени в стандартном бенчмарке async_generators для CPython тратилось на создание и уничтожение объектов исключений StopIteration. Эти объекты использовались как внутренний интерфейс для передачи данных между функциями на языке C.
Проблема заключалась в том, что функция PyAsyncGenASend_Send при каждом вызове аллоцировала исключение, упаковывала в него значение и сразу же уничтожала его после извлечения данных. Вложенные генераторы приводили к повторению этих операций на каждом уровне.
Для оптимизации был добавлен C-хелпер async_gen_unwrap_send, который возвращает статус через enum PySendResult и передает значение через указатель. Это позволило избежать работы с тредом и исключениями при передаче данных внутри рантайма.
Дополнительно была оптимизирована функция async_gen_asend_dealloc. Теперь вызов тяжелого финализатора PyObject_CallFinalizerFromDealloc происходит только для корутин в начальном состоянии, что исключает лишние проверки для уже запущенных или закрытых объектов.
Внесенные в genobject.c правки обеспечили ускорение бенчмарка в 1,33–1,53 раза. Патч успешно прошел полный набор из 491 теста Python, при этом показатели остальных тестов из пакета pyperformance остались в пределах погрешности измерений.




