Deep Engineering

ЗАМЕР

bench/goescape/decisions.sh

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

Цитируется в статье
/ru/interview/golang/escape-analysis

Запись прогона

У этого замера записи прогона нет — только скрипт.

Скрипт

39 строк
#!/usr/bin/env bash
#
# Решения escape-анализа, напечатанные самим компилятором.
#
# ЗАЧЕМ ОТДЕЛЬНЫЙ СКРИПТ. Число выделений (`testing.AllocsPerRun`) отвечает на
# вопрос «сколько», но не на вопрос «почему именно это». Флаг `-m` заставляет
# компилятор назвать своё решение по каждому значению — и это единственный
# способ проверить объяснение, а не поверить ему.
#
# ПОЧЕМУ -l. Без него компилятор встраивает мелкие функции, и решения
# печатаются про тела, которых в итоговом коде уже нет. С `-l` строки отчёта
# соответствуют исходнику один к одному.
#
# ПОЧЕМУ ВЫВОД ФИЛЬТРУЕТСЯ. Полный отчёт содержит десятки строк про
# внутренности `testing` и `fmt` — они верны, но к уроку отношения не имеют.
# Оставлены только строки про четыре функции задачи 1, то есть ровно те, чьи
# числа урок и объясняет.
#
# ЗАПУСК:
#
#	bash bench/goescape/decisions.sh
set -u

cd "$(dirname "$0")"

echo "go build -gcflags='-m -l' | решения компилятора"
echo

# Диапазон строк задачи 1: от объявления local() до конца intoInterface().
go run -gcflags='-m -l' practice.go 2>&1 |
	grep -E '^\./practice\.go:(3[6-9]|4[0-9]|5[0-8]):' |
	grep -E 'escape|moved to heap'

echo
echo "  Читается так: «does not escape» — значение осталось в кадре,"
echo "  «escapes to heap» — обязано его пережить. Обратите внимание на"
echo "  первую строку: там взят АДРЕС локальной структуры, и компилятор"
echo "  всё равно оставил её на стеке."