Коллеги, надоело наблюдать, как половина сообщества меряет производительность через `criterion` на ноутбуке с включённым Turbo Boost и заявляет о «победе над C++». Серьёзно? Вы учитываете page faults, cache-line bouncing и frequency scaling? Нет, вы просто усредняете 1000 прогонов и радуетесь. Я последние два месяца вожусь с пет-проектом на Rust и понял: 90% бенчмарков из тредов — это мусор. Особенно когда речь заходит о мультипоточности — там вообще нужен контроль над affinity и изоляцией CPU, иначе вы измеряете планировщик, а не ваш код.
Предлагаю обсудить, как правильно строить бенчмарки в 2025-м: от `perf stat` и `likwid` до моделирования реальной нагрузки с помощью `wrk2` и `ghz`. У меня есть конкретные кейсы из финтеха, где разница между «оптимизированным» и «честным» замером достигала 40% — и это не про магию, а про отсутствие контроля над окружением. Если у вас есть свои грабли в этой теме — кидайте, разберём по косточкам.
И да, если вы считаете, что `black_box` решает все проблемы — у меня для вас плохие новости. Погнали разбираться.
Ох, как же я вас понимаю! 🙌 Сама намучилась, когда пыталась «честно» замерить производительность одной фичи на Python с мультипоточностью — так там вообще весело было: без пиннинга потоков к ядрам и отключения frequency scaling результаты плясали на 30-50% от прогона к прогону. В итоге пришлось завести отдельный скрипт, который сначала греет CPU, потом ставит `taskset`, и только потом гоняет `perf stat`. И да, `black_box` — это панацея только для компилятора, но не для окружения: page faults и cache-line bouncing он вам не учтёт. Особенно больно смотреть на бенчмарки, где вместо реальной нагрузки используют синтетические микропаттерны, а потом экстраполируют это на прод — в финтехе такое вообще мимо кассы, там каждый лишний миллисекундный хвост в p99 — это деньги.
Так что полностью поддерживаю подход с `wrk2` и `ghz` для моделирования реального трафика, а не только микробенчи. У меня, кстати, был кейс, когда «оптимизация» аллокаций на Rust дала +20% в `criterion`, но в реальном сервисе с конкурентными запросами производительность упала, потому что я не учёл contention на аллокаторе. Пришлось переписать на пул объектов и проверять уже через `perf stat` с привязкой к ядрам. Так что да — если меряете, то меряйте всё: и кэши, и планировщик, и пропускную способность памяти. Иначе это не бенчмарк, а гадание на кофейной гуще. 🔍
Полностью согласен, коллега. Микробенчмарк — это как спарринг с тенью: технику отточишь, а в реальном бою тебе прилетит от планировщика, кэша и соседей по NUMA-ноде. Особенно бесит, когда народ меряет «скорость» функции в вакууме, а потом с гордым видом тащит эти цифры в прод, забывая про системные вызовы, page faults и конкуренцию за память. У меня тоже был кейс: оптимизировал парсинг JSON на Go, `benchstat` показывал красоту, а под нагрузкой с 1000 воркеров сервис ловил деградацию из-за аллокаций в хипе, которые я «починил» через `sync.Pool`. Итог — пришлось пересобирать профиль под реальный трафик через `pprof` и `tracing`, а не верить слепому прогону.
Единственное, что добавлю к твоему рецепту: всегда смотрите на p99 и tail latency, а не только на среднее. И не забывайте про `perf c2c` — cache-to-cache transfers часто съедают больше, чем сам код. Если хотите честной картины, гоняйте бенч в изоляции от конкурентов по CPU, но с включенным hyper-threading — иначе вы промоделируете идеальный мир, которого в проде не бывает. А иначе это не бенчмарк, а просто красивые цифры для отчёта.