refal-5-lambda
refal-5-lambda copied to clipboard
Кэширование компилируемых файлов
Мотивация
Мотивация простая — ускорение работы компилятора. На данный момент самоприменение самого компилятора (rlc-core
) требует нескольких десятков секунд.
Другая мотивация — обеспечить для rl-refgo-wrapper
(см. #334) более-менее приемлемое время работы.
Реализация
Фактически, это будет Ccache (https://ccache.dev/), встроенный в компилятор. Или некий аналог Zapcc (#177) — кэширующего компилятора C++ на основе Clang.
Компилятор должен принимать флаг --cache-dir=…
, в котором указывается папка кэша .rasl
’ов (и, возможно, .cpp
-шек). Пустой параметр командной строки отключает кэш.
На данный момент на результат трансляции влияют помимо содержимого самого файла также флаги компиляции (-O…
и --markup-context
) и содержимое всех прямо или косвенно подключаемых включаемых файлов. Следовательно, все эти данные должны учитываться.
Кэширование планируется осуществлять по хэшу, вычисляться хэш должен будет от содержимого файла, включаемых файлов и используемых ключей компилятора. Предлагается использовать хеш-функцию Дженкинса lookup3
, т.к. она уже реализована в компиляторе. Криптографической безопасности не требуется, достаточно минимизации коллизий. Хеш-функция даёт два 32-разрядных числа, что даёт шанс коллизии 1 на 4 миллиарда (атака дней рождения). Если компиляцию вызывать каждые 5 минут, на каждой перекомпиляции менять по 3 файла, то за рабочий день (8 часов) наберётся 12×3×8=288 файлов. За год 288×366 = (327 + 39)×(327 − 39) = 327² − 39² ≈ 320² − 40² = 102 400 − 1600 ≈ 100 000 файлов. За 10 лет — миллион, что много меньше 4 млрд. Коллизия невероятна.
После отказа от включаемых файлов (#318) хешировать потребуется прелюдию, опции и сам файл.
Предлагается дополнить модуль Hash
функцией HashLittle2-File
, которая принимает не строку character’ов, а имя файла — так она будет эффективнее.
Кэширование можно выполнять не на уровне rlc
, а на уровне rlmake
. Следует обдумать оба варианта.
Вычисление хэша должно выполняться до лексического анализа, что затрудняет поиск $INCLUDE
. Можно поступить так, как это сделано в rlmake
— распознавать $INCLUDE
только в одиночных строчках. Но тогда возможны ошибки в обе стороны — ложноположительные ошибки, когда эта строка находится внутри многострочного комментария, ложноотрицательные, когда директива находится не в отдельной строке. Поэтому проще дождаться удаления $INCLUDE
из компилятора (#318).