Основные улучшения:
- В основной состав включён парсер Prism, реализованный в форме Си-библиотеки libprism, задействованной в интерпретаторе CRuby, и gem-пакета на языке Ruby, предоставляющем общедоступный API для нисходящего рекурсивного разбора кода на языке Ruby, пригодный для использования в рабочих проектах вместо парсера Ripper. Из достоинств Prism отмечается хорошая переносимость и гибкая обработка ошибок в коде. Для включения нового парсера можно использовать опцию «ruby —parser=prism» или переменную окружения RUBYOPT=»—parser=prism». Для разбора кода в своих программах доступны методы Prism.parse(source) для получения AST-представления кода,
Prism.parse_comments(source) для выделения комментариев из кода и Prism.parse_success?(source) для проверки наличия ошибок в коде. - Вместо внешнего пакета Bison для генерации парсеров задействован проект Lrama, предоставляющий реализацию алгоритма LALR на языке Ruby, поддерживающий Bison-совместимые определения грамматик (parse.y), используемые в CRuby, и реализующий расширенные возможности, такие как обработка ошибок и параметризированные правила (?, *, +).
- Проведена значительная оптимизация производительности JIT-компилятора YJIT, развиваемого разработчиками платформы электронной коммерции Shopify в рамках инициативы по увеличению производительности Ruby-программ, использующих фреймворк Rails и вызывающих очень много методов. В отличие от ранее используемого JIT-компилятора MJIT новый YJIT применяет версионирование базовых блоков (LBBV — Lazy Basic Block Versioning) вместо обработки методов целиком и реализован в форме интегрированного JIT-компилятора, написанного на языке Rust. Благодаря LBBV, JIT вначале компилирует только начало метода, а оставшуюся часть компилирует через некоторое время, после того как в процессе выполнения будет определены типы используемых переменных и аргументов.
При тестировании выполнения эмулятора Optcarrot производительность при использовании YJIT более чем в три раза превышает выполнение при помощи интерпретатора. В новой версии обеспечено выделение регистров для стековых операций виртуальной машины, расширен спектр компилируемых вызовов с необязательными аргументами, реализовано inline-развёртывание базовых и специализированных методов, добавлены отдельные оптимизации для операций «Integer#*», «Integer#!=», «String#!=», «String#getbyte», «Kernel#block_given?», «Kernel#is_a?», «Kernel#instance_of?» и «Module#===». Значительно увеличена скорость компиляции.
Заметно снижено потребление памяти на хранение метаданных и обеспечена генерация более компактного кода для архитектуры ARM64. По умолчанию отключён сборщик мусора Code («—yjit-code-gc»), динамически высвобождающий неиспользуемый сгенерированный машинный код, но приводящий к проседанию производительности во время сборки мусора.
Добавлен метод RubyVM::YJIT.enable для управления включением YJIT во время работы, без необходимости запуска с определённым параметром командной строки или переменной окружения. Расширена статистика, выдаваемая при указании опции «—yjit-stats». Добавлены режимы профилирования производительности (—yjit-perf) и трассировки (—yjit-trace-exits). - Предложен новый JIT-компилятор RJIT, написанный целиком на языке Ruby и заменяющий MJIT, но в отличие от последнего при использовании не требующий Си-компилятора. RJIT поддерживает только архитектуру x86-64 и Unix-подобные платформы.
- Добавлен планировщик потоков «M:N», позволяющий для сокращения накладных расходов на создание и управление потоками использовать ограниченное число потоков операционной системы для обработки потоков в коде на языке Ruby. По умолчанию используется 8 потоков ОС (можно изменить через переменную окружения RUBY_MAX_CPU). Применение планировщика «M:N» может привести к проблемам с совместимостью с расширениями на языке Си, поэтому он отключён по умолчанию для основного (main) класса Ractor, но включён для неосновных (non-main). Для принудительного включения планировщика «M:N» следует выставить переменную окружения RUBY_MN_THREADS=1.
- Расширены возможности оболочки интерактивных вычислений IRB(REPL, Read-Eval-Print-Loop). Добавлен режим отладки irb:rdbg, эквивалентный по своим возможностям отладчику pry-byebug. Добавлена поддержка многостраничного просмотра вывода команд ls, show_source и show_cmds. Реализована экспериментальная поддержка автоматического дополнения ввода, учитывающая типы данных. Предоставлены команды для изменения цвета и стиля шрифта.
- Объявлен устаревшим вызов метода «it» без аргументов в блоке без параметров (например, «[1, 2, 3].each { puts it }»).
- В RubyGems и Bundler включён вывод предупреждения в случае указания в «require» gem-пакетов
abbrev,
base64,
bigdecimal,
csv,
drb,
getoptlong,
mutex_m,
nkf,
observer,
racc,
resolv-replace,
rinda и
syslog, если они не добавлены в Gemfile или gemspec. В будущих версиях Ruby данные gem-пакеты будут встроены в основной состав. - Обновлены версии встроенных и входящих в стандартную библиотеку gem-модулей.
Источник: http://www.opennet.ru/opennews/art.shtml?num=60347