Какое место занимают бенчмарки (benchmarks) в процессе сборки и тестирования Go-приложения?

Ответ

Бенчмарки являются частью этапа тестирования и выполняются после компиляции кода. Типичный пайплайн выглядит так:

  1. Статический анализ (Linting): Инструменты вроде go vet или golangci-lint проверяют исходный код на наличие ошибок, стилистических несоответствий и потенциальных проблем. Этот этап работает с исходным кодом, до компиляции.

  2. Сборка (Compilation): Команда go build компилирует исходный код в исполняемый бинарный файл.

  3. Тестирование (Testing): Этот этап запускается командой go test и включает в себя:

    • Юнит-тесты: Проверяют корректность логики. Они выполняются в первую очередь.
    • Бенчмарки: Запускаются с флагом -bench (например, go test -bench .). Они измеряют производительность (скорость выполнения, аллокации памяти) уже скомпилированного кода. Это важно, чтобы на результаты не влияло время самой компиляции.

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

Пример бенчмарка:

func BenchmarkSum(b *testing.B) {
    // b.N подбирается автоматически для получения статистически значимого результата
    for i := 0; i < b.N; i++ {
        Sum(1, 2)
    }
}

Ответ 18+ 🔞

Да ты посмотри, какая чёткая схема получается, аж приятно! Вот как у нас с кодом всё по полочкам раскладывается, блядь.

Сначала, сука, у нас идёт статический анализ, это типа как батя пришёл и начал проверять, ты квартиру убрал или нет. Инструменты вроде go vet или golangci-lint ползают по исходникам, выискивают, где ты накосячил со стилем или логику кривую написал. Главное — они это делают до того, как мы вообще собраться попробуем. С исходным кодом работают, пиздец.

Потом, естественно, сборка. Команда go build — это наш главный строитель, который из этой кучи текста делает уже настоящий, ебаный, исполняемый файл. Без этого нихуя не запустится.

А вот дальше самое интересное — тестирование. Тут команда go test рулит, и внутри неё два главных героя, блядь:

  • Юнит-тесты — это как проверка, работает ли вообще твоя хитроумная хуйня. Кнопку нажал — свет зажёгся? Вот это они.
  • А бенчмарки — это уже замеры скорости, сука! Запускаются они с флагом -bench (типа go test -bench .). И вот тут ключевой момент, ёпта: они гоняют уже скомпилированный код! Чтобы время, которое компилятор тупил, не засчитывалось в результат. Чистая производительность, ядрёна вошь!

Короче, бенчмарк — это не про то, работает или нет, а про то, как быстро оно работает. Инструмент для замеров на этапе тестирования, когда бинарник уже готов.

Вот, смотри, как это выглядит в коде, простой пример:

func BenchmarkSum(b *testing.B) {
    // b.N подбирается автоматически для получения статистически значимого результата
    for i := 0; i < b.N; i++ {
        Sum(1, 2)
    }
}

Видишь? Цикл, который гоняет функцию Sum столько раз, сколько надо для точного замера. Всё честно, без обмана.