Отбрасывание недостижимого на стороне flang даёт тот же ответ и стоит в 180 раз дороже
flang/src/reachable.mjs — 248 строк JavaScript в рабочем пути flang check, и сторона на flang у него УЖЕ ЕСТЬ: «Отбросить недостижимое» в flang/self/link.flang. Ответы совпадают. Переключать всё равно нельзя, и довод не «дорого вообще», а «дорого ровно там, где это стоит на горячем пути».
Чем подтверждено. Прогон 19 августа на ветке work/nepodvizhnaya-tochka поверх ствола 2bfcb7d0. Обе реализации звались на одной и той же отмеченной программе, время — performance.now() вокруг вызова:
| программа | функций | JavaScript | сторона на flang | во сколько раз |
|---|---|---|---|---|
examples/import-check.flang | 29 | 1 мс | 106 мс | 165 |
flang/self/emit-c.flang | 547 | 24 мс | 1 947 мс | 80 |
flang/self/bootstrap/compiler.flang | 3 616 | 143 мс | 25 905 мс | 181 |
Плюс 686 мс на сборку слоя link.flang при первом спросе. Ответы совпали на всех трёх, включая урезание 3 616 → 3 587 функций у самого компилятора.
Почему это отказ, а не «пока подождём». Отбрасывание недостижимого стоит на пути КАЖДОЙ печати во все восемь целей (flang/bin/flang.mjs, единственный вызов dropUnreachable). 26 секунд вместо 143 миллисекунд на собственном компиляторе — это не размен по времени, это другая команда: flang emit из секундной становится минутной.
Чем ограничено. Число — про слой, который едет ВЫЧИСЛИТЕЛЕМ. Собранный двоичный компилятор считает то же самое машинным кодом, и к нему этот замер не относится вовсе. То есть отказ здесь — от «звать сторону из рабочего пути интерпретируя», а не от стороны как таковой.
Побочное, найденное тем же заходом. Проверка «долг не вырос» (flang/test/rabochiy-put.test.mjs) искала сторону в файле того же имени — flang/self/reachable.flang, — не находила и МОЛЧАЛА. То есть готовая сторона не попадала в долг именно потому, что её назвали иначе: она живёт внутри link.flang. Это тот же класс, что «переименование файла молча выключает проверку»: соответствие имён надо задавать таблицей, а не соглашением.
Поправка 19 августа: цена подтвердилась, а вывод «остаётся навсегда в рабочем пути» — нет. Здесь и в docs/javascript-removal.md стояло, что модуль остаётся в рабочем пути flang check. Он из него ушёл, и переключать решение при этом не пришлось.
Цена перемерена на дереве ветки work/zelenyy-stvol тем же способом: ×203 на import-check.flang (1 мс против 160), ×116 на self/emit-c.flang (19 против 2 262), ×192 на самораскрутке (164 мс против 31 494), сборка слоя 981 мс, ответы совпали побайтово на всех трёх. Отказ от переключения в силе.
Но flang check dropUnreachable НЕ ЗОВЁТ НИ РАЗУ — он нужен одной команде emit. В перепись модуль попадал потому, что ввоз стоял статической строкой наверху flang/bin/flang.mjs и грузился в каждую команду. Ввоз отложен внутрь commandEmit, и 248 строк ушли из переписи, не тронув ни цены, ни ответа: печать считает тем же JavaScript, что и считала.
Урок общий, и он не про этот файл: документ, меряющий цену переключения, не отвечает на вопрос про загрузку, и наоборот. Пока оба числа не названы порознь, две записи об одном файле выглядят противоречащими, хотя говорят о разном.
Связано: removed-from-the-decision-and-removed-from-the-load-are-two-events, a-side-may-already-exist-check-before-writing, renaming-a-file-silently-disables-the-guard, four-pieces-of-javascript, a-ratchet-instead-of-derivation