shikhalev.org

Подумалось: а ведь скриптовые интерпретируемые языки вполне способны на не­ко­то­рых задачах обгонять компилируемые и сильно, если программу не исполнять, а вычислять как формулу — это же совершенно не обязательно делать по-порядку. Можно «раскрыть скобки», «привести подобные», «сократить»… Соременные компиляторы, собственно, так и делают, но они могут зафиксировать только параметры, известные на этапе компиляции, а для прочих приходится учитывать все возможные комбинации значений, тогда как при ка­ж­дом конкретном запуске программы их подмножество существенно ограничено. Многие вещи — такие как: переменные среды, параметры командной строки и т.д. — определяются при старте и далее могут считаться константами, соответственно, упрощаются выражения от них и т.д.

Понятно, что это упрощение дальнейших выражений не бесплатное: скорее всего, скажем, удаление неиспользуемых ветвлений будет требовать больше ресурсов, чем вычисление этих условий по ходу дела, но ежели эти условия и другие выражения должны вычисляться многократно… Скажем, для вебсервера время старта куда менее критично, чем время отклика на запрос.

Что для этого нужно? Во-первых, структурированное внутреннее представление, с которым можно манипулировать как с фор­му­лой — это не текст и не байт-код (в Ruby свежих версий именно так). Во-вторых, необходимо как-то определять наличие побочных эффектов (в Ruby это, пожалуй, может быть довольно просто реализовано для собственно ruby-методов, а вот с мо­ду­ля­ми, загружаемыми как .so и .dll будет проблема. Впрочем, достаточно к нескольким системным фунциям типа define_method добавить соответствующие описательные параметры). И в-третьих, желательна жесткая инкапсуляция данных, так что Ruby для этой цели подходит, а вот, скажем, JavaScript — намного хуже.

А пока такой оптимизации нет, наверное, можно подумать о том, чтобы в своих программах не только вычислять какие-то параметры один раз при старте, но формировать код в зависимости от них…