#производительность

13 posts

2026-10-14 23:59

Автор: Кирилл Борисов · PyCon Russia 2016


Профилировщик легко находит функции, в которых программа проводит больше всего времени. Трудности начинаются после этого: таблица сообщает, что дорого, но часто не объясняет, как исполнение туда попало и почему этот путь оказался настолько частым.

Кирилл Борисов показывает, как sampling profiling превращает работу программы в набор снимков стека. Вместо инструментирования заранее выбранных функций профайлер периодически фиксирует весь текущий путь вызовов. Такой сбор пропускает короткие события и не даёт точной хронологии, зато меньше вмешивается в выполнение программы и сохраняет контекст: не только работающую функцию, но и цепочку, которая к ней привела.

Проблема в объёме. На реальном приложении быстро появляются тысячи и миллионы стеков, а плоский отчёт сводит их к отдельным строкам. Flame graph агрегирует одинаковые пути и превращает их в интерактивную карту. Ширина блока показывает, в какой доле сэмплов встречался соответствующий стек, а вертикаль сохраняет иерархию вызовов. Поэтому на графике можно увидеть не просто дорогую функцию, а разные маршруты, из которых она была вызвана.

Доклад записан в 2016 году: конкретные Python-инструменты и способы их подключения стоит воспринимать как исторический контекст. Сам подход не устарел — flame graph остаётся одним из основных представлений для sampling и continuous profiling.

Кому смотреть: разработчикам, которые уже запускали профайлер, получали длинную таблицу функций и не понимали, с какого места начинать расследование.

Из этого можно взять в работу: при следующем исследовании производительности сохранять не только суммарную стоимость функций, но и полные стеки вызовов — причина дорогого участка может находиться выше по пути исполнения.

Read more →
0
2026-10-09 21:13

Авторы: Ирина Блажина и Николай Зайцев · HighLoad Channel


В X5 Tech несколько продуктов использовали собственные системы аутентификации. Пользователям приходилось заново входить в разные сервисы и получать дополнительные SMS, а команды независимо поддерживали код, связанный с безопасностью. Единый SSO должен был решить обе проблемы.

Основой системы стал Keycloak. Его возможностей хватало для обработки входов, но при росте аудитории команда столкнулась с другим ограничением: время запуска зависело от количества сохранённых сессий. Так задача масштабирования SSO превратилась в разбор кэшей, rolling updates, PostgreSQL и устройства самого Keycloak.

Кому смотреть: командам, которые внедряют централизованную аутентификацию, расширяют Keycloak собственными providers или готовят SSO к большой аудитории.

Из этого можно взять в работу: проверять identity-сервис не только под потоком входов, но и при полном перезапуске кластера с реальным объёмом пользовательских сессий.

Read more →
0
2026-10-07 22:49

Автор: Дмитрий Ходаков · PyCon Russia 2018


В 2015 году команда Авито выбрала Tornado по правильным причинам. Фреймворк был зрелым, выдерживал production-нагрузку и располагал библиотеками для нужных баз данных. На его основе собрали общий шаблон, от которого затем выросли десятки микросервисов.

Через три года сервисы продолжали работать, но изменился сам Python. Нативные async/await и стандартный asyncio сформировали другую модель асинхронного приложения. Tornado тоже развивался, однако за ним тянулись генераторы, глубокие стеки и собственные исторические абстракции. Когда рядом появился aiohttp, прежний разумный выбор начал обходиться дороже нового — хотя формально ничего не сломалось.

Доклад Дмитрия Ходакова полезен в 2026 году именно этой историей. У технологического решения нет вечного преимущества: оно принимается в конкретной экосистеме и может пережить причины, по которым его когда-то выбрали.

Кому смотреть: техническим руководителям и backend-разработчикам, которые поддерживают исправную, но давно выбранную платформу и не понимают, достаточно ли этого для продолжения работы с ней.

Из этого можно взять в работу: периодически восстанавливать исходные причины технологического выбора и проверять, остаются ли они верными после изменений языка, стандартной библиотеки и экосистемы.

Read more →
0
2026-10-05 22:10

Автор: Александр Луценко · HighLoad Channel


Профиль показывает, где программа тратит процессорное время. Из этого легко сделать лишний вывод: если внутри обработчика всё быстро, то и пользователь должен получить быстрый ответ. В production между этими двумя утверждениями могут находиться очередь, исчерпанные воркеры, сеть и другие части системы, которые профилировщик кода не видит.

Александр Луценко рассказывает, как команда перенесла профилирование с dev-окружения в production и превратила его в постоянный observability-сигнал. Мотивация проста: stage отличается от production железом, данными и формой нагрузки. Даже хороший нагрузочный тест не воспроизводит все сочетания условий, которые возникают в реальной системе.

Для сбора команда выбрала sampling profiler в отдельном sidecar-контейнере. Он не требовал менять код приложения или устанавливать расширение внутрь процесса. Профили отправлялись в коллектор, фильтровались, агрегировались и дополнялись метками сервиса, окружения и транзакции. Так отдельный flame graph превращался в историю поведения приложения между релизами.

Но постоянный сбор не делает профилирование полной моделью запроса. В одном из примеров endpoint внутри приложения выполнялся за миллисекунды, тогда как внешние измерения показывали ответ до трёх секунд. Причиной оказался недостаток воркеров: запросы долго ждали очереди перед тем, как попасть в быстрый обработчик.

Кому смотреть: backend- и platform-командам, которые хотят профилировать production или уже собирают профили, но рассматривают их отдельно от метрик и distributed tracing.

Из этого можно взять в работу: при расследовании медленного запроса разделять время ожидания до входа в код, выполнение самого кода и дальнейший путь ответа — одного профиля процесса для этого недостаточно.

Read more →
0
2026-09-28 22:18

Автор: Ильяс Салихов · PHP Russia 2022


ORM умеет сгенерировать миграцию, но не знает, выдержит ли её production. На таблице в сто миллионов строк обычный UPDATE, добавление ограничения или перестройка связей могут надолго занять базу блокировками. Формально схема обновляется правильно — а приложение в это время отвечает ошибками.

Ильяс Салихов показывает, как RetailCRM работает с PostgreSQL при постоянной нагрузке около 100 тысяч транзакций в секунду. Самая полезная часть доклада — не отдельные настройки PostgreSQL, а отношение к изменению схемы как к серии совместимых релизов. Новая структура сначала появляется рядом со старой, приложение некоторое время пишет в обе, данные переносятся порциями, чтение переключается отдельно — и только после проверки удаляется прежняя модель.

Кому смотреть: backend-разработчикам, которые применяют миграции во время обычной работы приложения и не могут выделить для них отдельное окно обслуживания.

Из этого можно взять в работу: на review следующей большой миграции отдельно проверить, совместим ли каждый её этап и можно ли остановиться или откатиться между этапами.

Read more →
0
2026-09-23 22:35

Автор: Григорий Петров · MoscowPython


О GIL часто говорят как об одном большом запрете: Python якобы не умеет работать с потоками. Из такого объяснения невозможно понять ни то, почему ограничение появилось, ни то, почему сетевые программы всё же получают пользу от потоков, ни то, какие ошибки GIL предотвращает на самом деле.

Григорий Петров начинает с истории процессов и потоков, а затем постепенно подводит к устройству CPython. Потоки делят память одного процесса, поэтому интерпретатор должен сохранять целостность своих внутренних структур, даже если операционная система переключит выполнение в неудобный момент. GIL даёт право исполнять Python bytecode одному потоку за раз и тем самым упрощает защиту состояния интерпретатора.

Но действие этого ограничения уже, чем кажется. Во время многих блокирующих операций ввода-вывода GIL освобождается, поэтому другие потоки могут продолжать работу. Нативные библиотеки также могут выполнять тяжёлые вычисления вне интерпретатора без удержания GIL. Главное историческое ограничение относится к CPU-bound коду, который исполняет Python bytecode и пытается использовать несколько ядер с помощью потоков.

Важно для 2026 года: доклад описывает стандартную модель CPython с GIL, которая по-прежнему используется по умолчанию. В CPython 3.13 появилась экспериментальная free-threaded сборка, а в Python 3.14 она стала официально поддерживаемой, но осталась опциональной. Поэтому ограничение CPU-bound потоков уже не абсолютно, однако совместимость расширений, накладные расходы и корректность многопоточного кода всё ещё требуют отдельной проверки.

Кому смотреть: Python-разработчикам, которым нужен не очередной совет «используйте процессы», а связная модель того, зачем существует GIL и где проходит граница его влияния.

Из этого можно взять в работу: перед выбором потоков, процессов или async определить, где задача проводит время: в Python bytecode, нативных вычислениях или ожидании ввода-вывода.

Read more →
0
2026-09-21 22:34

Автор: Антон Титов (SpiralScout) · PHP Russia 2019


Классическая модель PHP начинает каждый запрос почти с чистого состояния: загружает приложение, создаёт контейнер и после отправки ответа освобождает процесс. RoadRunner сохраняет PHP worker между запросами — и тем самым превращает прежнюю гарантию очистки в ответственность разработчика.

Антон Титов показывает гибридную архитектуру, в которой сервер на Go принимает запросы и управляет долгоживущими PHP-процессами. Приложение не нужно загружать заново для каждого обращения, поэтому уменьшается стоимость инициализации. На уровне HTTP автор заявляет ускорение примерно в двадцать раз, хотя такой результат относится к конкретному benchmark, а не к любому PHP-проекту.

У производительности есть обратная сторона. Объект, соединение или пользовательский контекст теперь способны пережить запрос, для которого были созданы. PHP-приложение должно работать как настоящий долгоживущий сервис, а не рассчитывать, что процесс автоматически уничтожит всё состояние.

Кому смотреть: PHP-разработчикам, которые рассматривают RoadRunner, FrankenPHP или другую модель долгоживущих workers.

Из этого можно взять в работу: проверить сервисы и singleton-объекты приложения на данные текущего пользователя, запроса или транзакции, которые могут остаться в памяти после ответа.

Read more →
0
2026-09-09 23:56

Автор: Александр Боргардт (duckstax) · Evrone Development


У питонистов есть простое правило: хочешь сделать быстро — пиши нативный код. Это действительно так, когда нативный код пишут опытные C/C++-разработчики. Но те, кто только начинает погружаться в эту область, часто обнаруживают что стало не быстрее, а медленнее. Боргардт объясняет почему — и как это исправить.

Реальный кейс: ML pipeline с видеопотоком, задача — поиск объектов в кадре в реальном времени. На каком-то этапе всё начало тормозить. Расследование привело не к проблеме в алгоритме, а к проблеме на границе Python–C++: неявные накладные расходы при вызове нативного кода из Python.

Кому смотреть: Python-разработчикам, которые пишут или планируют писать C++-расширения — и хотят понять, почему «просто вынести в C++» не всегда означает «стало быстрее».

Из этого можно взять в работу: если пишете C++-модуль для Python и работаете с большими массивами данных — изучите Buffer Protocol (PEP 3118). Это стандартный механизм zero-copy передачи данных между Python и нативным кодом, который поддерживают numpy, bytearray, bytes.

Read more →
0
2026-09-07 23:44

Автор: Даниил Коноваленко (Яндекс Go) · Python Channel · Moscow Python Conf++ 2021


Даниил Коноваленко — backend-разработчик в Яндекс Go. В подразделении несколько сотен микросервисов, треть из них написана на Python. Однажды во время дежурства пришёл алерт: один из сервисов занял 91% памяти. Открыв графики — всё выглядело нормально. Открыв на большем масштабе — характерный паттерн: память растёт линейно и никогда не возвращается. После перезапуска — то же самое. Это и есть утечка.

Доклад — детективная история с реальным production-кейсом. Три акта: как утечка выглядит и как её опознать, откуда они берутся в языке с GC, какие инструменты помогают найти и исправить.

Кому смотреть: backend-разработчикам на Python, которые деплоят сервисы в production и уверены что GC за них всё уберёт. После этого доклада — чуть менее уверены, зато знают что делать.

Из этого можно взять в работу: если у вашего сервиса есть метрика потребления памяти — посмотрите на неё на масштабе нескольких дней. Линейный рост без возврата после GC-цикла — сигнал для расследования, а не повод «накинуть памяти и посмотреть».

Read more →
0
2026-08-28 23:30

Автор: Антон Алексеев · HighLoad++ 2024


Доклад с HighLoad++ 2024 о том, как Selectel собирал инференс-платформу на базе open source-сервера NVIDIA Triton и Kubernetes. Triton решает базовую задачу: позволяет обслуживать ML-модели в продакшне без написания отдельного сервиса для каждой модели с нуля.

Сценарий типичный: модель сначала заворачивают в FastAPI, а затем обвязка постепенно обрастает batching, управлением инстансами, распределением GPU-ресурсов, обновлением версий и маршрутизацией трафика. Triton закрывает существенную часть этой базовой работы: умеет динамический batching, поддерживает модели в форматах PyTorch, TensorFlow, ONNX и TensorRT, а ensemble позволяет собрать цепочку моделей внутри одной ноды с одной GPU.

Но production-инференс начинается там, где заканчивается сам сервер моделей. Канареечное распределение трафика в платформе сделано через Istio, графы моделей на нескольких нодах — через Ray, а автоскейлинг GPU-ресурсов — средствами Kubernetes и дополнительными компонентами. Важная деталь: на момент доклада платформа Selectel ещё находилась в beta, поэтому это не история про «готовое решение из одной коробки», а разбор того, как такую систему собирают на практике.

Кому смотреть: ML-инженерам, MLOps- и DevOps-командам, которые обслуживают несколько моделей на GPU и хотят понять границу между возможностями inference-сервера и задачами всей платформы.

Из этого можно взять в работу: при внедрении Triton заранее разделите требования на две группы — что должен делать сам сервер моделей, а что потребует Kubernetes, service mesh, автоскейлинга, GPU-оператора или отдельного control plane.

Read more →
0
2026-08-24 23:41

Автор: Дмитрий Стогов (Zend Technologies) · PHP Russia 2019


⚠️ Доклад 2019 года — за год до выхода PHP 8.0 (ноябрь 2020). Это анонс и технический разбор того, что готовилось. JIT, Preloading и FFI с тех пор вышли в стабильных версиях; суть механизмов Стогов объясняет точнее, чем большинство статей, написанных постфактум.


Дмитрий Стогов — один из ключевых людей за производительностью PHP. Автор Turck MMCache (eAccelerator), мейнтейнер Zend OPcache, лидер проекта PHPNG, который лёг в основу PHP 7 и дал двукратный прирост производительности без изменения синтаксиса. Теперь — лидер разработки JIT-компилятора для PHP 8. Когда он рассказывает о производительности PHP — это рассказ от человека, который её делал.

Три новых подсистемы PHP 8 — JIT, Preloading и FFI — Стогов рассматривает как взаимосвязанные. Все три направлены на производительность, но также открывают PHP новые области применения: писать системно-зависимые расширения прямо на PHP, подключать сторонние C-библиотеки, быстро прототипировать низкоуровневые вещи.

Кому смотреть: PHP-разработчикам, которые хотят понять JIT, FFI и Preloading не через «что делать в коде», а через «как это устроено и зачем» — от человека, который это написал.

Из этого можно взять в работу: если ваш PHP-сервис тяжело нагружен CPU-вычислениями (а не I/O) — именно для таких сценариев JIT даёт реальный прирост. Для типичного CRUD с базой данных эффект от JIT минимален — и Стогов об этом говорит честно.

Read more →
0
2026-07-08 21:29

Автор: Михаил Жилин · HighLoad++ Channel


Доклад с HighLoad++ 2024, 50 минут. PostgreSQL — база, которую хорошо знают и любят. Но поведение под нагрузкой — это другая тема: здесь включаются механизмы, которые в обычной работе не видны и в документации описаны скромно.

Жилин разбирает аномалии, которые проявляются именно под нагрузкой: как MVCC-механизм начинает накапливать мёртвые версии строк быстрее, чем autovacuum успевает их убирать; как это влияет на размер таблиц и производительность запросов; какие блокировки возникают там, где их не ждёшь; как connection pool ведёт себя при спайках и почему «просто увеличить max_connections» решает одну проблему и создаёт две новых. Доклад не обзорный — это конкретный производственный опыт с цифрами и конфигурациями.

Кому смотреть: разработчикам и DBA, которые эксплуатируют PostgreSQL под реальной нагрузкой и хотят понять, почему база «начала тормозить» — и особенно тем, кто ещё не сталкивался с bloat и autovacuum lag, пока они не случились в продакшне.

Из этого можно взять в работу: посмотрите на размер ваших самых активно обновляемых таблиц через pg_stat_user_tables — n_dead_tup / n_live_tup. Если соотношение высокое, у вас есть bloat, который под нагрузкой превратится в деградацию производительности.

Read more →
0
2026-07-06 22:26

Автор: Андрей Аксенов · Podlodka Podcast


Андрей Аксенов — автор поискового движка Sphinx и человек, который писал собственные хэш-таблицы тогда, когда это ещё было нормальной практикой. Выпуск Podlodka #464 — не обзор структур данных, а разговор с человеком, который знает, где у хэш-таблиц болевые точки.

Хэш-таблицы — та структура данных, которую все используют и почти никто не понимает глубоко. Большинство разработчиков знают про O(1) в среднем и помнят что-то про load factor «меньше 0.75». Аксенов разбирает, откуда берутся эти числа, почему они не универсальны, и что реально происходит с производительностью, когда таблица растёт. Центральный тезис: поведение хэш-таблицы определяется не только алгоритмом, но и характером данных и паттерном доступа — и одна реализация не может быть одинаково хороша везде.

Разговор про open addressing особенно ценен: это техника, которая лежит в основе многих стандартных библиотек, но редко объясняется на уровне «почему именно так, а не иначе».

Кому смотреть: разработчикам, которые хотят понимать, что происходит внутри HashMap в их стандартной библиотеке, и тем, кто сталкивается с перформанс-проблемами в коде, который «должен работать быстро».

Из этого можно взять в работу: в следующий раз, когда выбираете или конфигурируете хэш-таблицу, спросите себя: какой у нас паттерн доступа — много reads или много writes, известен ли размер заранее, однородны ли ключи. Ответы на эти вопросы определяют выбор лучше, чем любой дефолтный load factor.

Read more →
0