ЗАМЕР
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 " всё равно оставил её на стеке."