MEASUREMENT
bench/goescape/decisions.sh
The script that produced the numbers in the article, and the record of the run. The file is read from the repository at build time — this is the code that was run, not a copy of it.
The run below is recorded in Russian. It is a lab record, kept in the language it was written in; the numbers, the tables and the code read the same either way.
Record of the run
This measurement has no recorded run — only the script.
Script
39 lines#!/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 " всё равно оставил её на стеке."