Почему мой бенчмарк врал на 30%

3 ноября 2025 · 5 минут

Я сравнивал две реализации хеш-таблицы и получил разницу в 30% в пользу новой. После пары часов проверок выяснилось, что разница была почти целиком в условиях замера, а не в коде. Записываю, что пошло не так.

1. Частота процессора плавает

Первый прогон шёл на холодном процессоре с полным Turbo Boost, второй — после того как кристалл прогрелся и частота упала. Для честного сравнения частоту стоит зафиксировать:

sudo cpupower frequency-set -g performance
echo 1 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo

На AMD вместо no_turbo есть /sys/devices/system/cpu/cpufreq/boost.

2. Соседи по ядру

Планировщик переносил процесс между ядрами, а на соседнем логическом ядре (SMT) крутился браузер. Привязка к конкретному ядру убирает большую часть шума:

taskset -c 3 ./bench --impl=new

3. Нет прогрева

Первые итерации платят за промахи кэша, page faults и предсказатель ветвлений, который ещё ничему не научился. Несколько итераций до начала замера стоит выбрасывать.

4. Среднее вместо медианы

Один прогон, во время которого прилетело обновление пакетов, сдвигает среднее на проценты. Медиана и межквартильный размах по 20–30 запускам намного устойчивее. Удобно смотреть через perf stat -r 30 — он заодно покажет разброс.

Итог

После всех исправлений новая реализация оказалась быстрее на 4%, а не на 30. Вполне честный результат, просто куда менее впечатляющий.

perfbenchmarking