Ruby 3.3.0 正式发布

2023年 12月 26日 58.7k 0

Ruby 3.3.0 现已正式发布。新版本添加了一个名为 Prism 的新解析器,使用 Lrama 作为解析器生成器,添加了一个名为 RJIT 的新纯 Ruby JIT 编译器,以及许多性能改进,尤其是 YJIT。

具体更新内容如下:

Prism

  • 引入 Prism 解析器作为默认 gem
    • Prism 是一个可移植、容错且可维护的 Ruby 语言递归下降解析器
  • Prism 已做好生产准备并积极维护,用户可以使用它代替 Ripper
    • 具体介绍可查看 Prism 的文档。
    • Prism 既是一个由 CRuby 内部使用的 C 库,又是一个可供任何需要解析 Ruby 代码的工具使用的 Ruby gem
    • Prism API 中值得注意的方法有:
      • Prism.parse(source)返回 AST 作为解析结果对象的一部分
      • Prism.parse_comments(source)返回 comments
      • Prism.parse_success?(source)如果没有错误,则返回 true
  • 现在可以使用ruby --parser=prismRUBYOPT="--parser=prism"尝试使用  Prism 编译器。值得注意的是,该 flag 仅用于调试。

使用 Lrama 代替 Bison

  • 用 Lrama LALR 解析器生成器替换 Bison [Feature #19637]
    • 更多详情可参阅Ruby Parser 的未来愿景
    • 为了便于维护,Lrama 内部解析器被替换为 Racc 生成的 LR 解析器
    • 支持参数化规则(?, *, +),将在 Ruby parse.y 中使用

YJIT

  • 相对 Ruby 3.2 的主要性能改进
    • 对 splat 和 rest 参数的支持已得到改进。
    • 为虚拟机的堆栈操作分配了寄存器。
    • 编译更多带有可选参数的调用。异常处理程序也被编译。
    • 不支持的调用类型和复态调用点不再退出到解释器。
    • Rails #blank?和specialized#present?等基本方法都是内联的。
    • Integer#*Integer#!=String#!=String#getbyte、 Kernel#block_given?Kernel#is_a?Kernel#instance_of?Module#===进行了特别优化。
    • 编译速度现在比 Ruby 3.2 稍快。
    • 现在比 Optcarrot 上的解释器快 3 倍以上
  • 与 Ruby 3.2 相比显着提高了内存使用率
    • 编译代码的元数据占用内存更少。
    • 当应用程序的 ISEQ 超过 40,000 个时,--yjit-call-threshold会自动从 30 提高到 120。
    • 添加--yjit-cold-threshold以跳过编译 cold ISEQ。
    • 在 Arm64 上生成更紧凑的代码。
  • Code GC 现在默认禁用
    • --yjit-exec-mem-size被视为新代码编译停止的硬限制。
    • 不会因 Code GC 导致性能突然下降。使用 Pitchfork 重新分叉的服务器上有更好的 copy-on-write 行为 。
    • 如果需要,仍然可以使用--yjit-code-gc启用 code GC
  • 添加RubyVM::YJIT.enable以便在运行时启用 YJIT
    • 无需修改​​命令行参数或环境变量即可启动 YJIT。Rails 7.2 将使用此方法默认启用 YJIT 。
    • 这也可用于仅在应用程序完成启动后启用 YJIT。如果想在启动时禁用 YJIT 的同时使用其他 YJIT 选项,可以使用--yjit-disable
  • 默认情况下提供更多 YJIT stats
    • 现在默认情况下还提供了yjit_alloc_size和更多与元数据相关的统计信息。
    • --yjit-stats生成的 ratio_in_yjitstat 现在可在发行版中使用,不再需要特殊的 stats 或 dev 版本才能访问大多数统计信息。
  • 添加更多 profiling 功能
    • 添加--yjit-perf以方便使用 Linux perf 进行分析。
    • --yjit-trace-exits现在支持使用--yjit-trace-exits-sample-rate=N进行采样
  • 更全面的测试和多个错误修复

RJIT

  • 引入了纯 Ruby JIT 编译器 RJIT 并取代了 MJIT。
    • RJIT 仅支持 Unix 平台上的 x86-64 架构。
    • 与 MJIT 不同,它在运行时不需要 C 编译器。
  • RJIT 的存在仅用于实验目的。
    • 建议用户在生产环境中继续使用 YJIT。
  • 如果对为开发 JIT for Ruby 感兴趣,可查看 k0kubun 在 RubyKaigi 第 3 天的演示。

M:N 线程调度器

  • 引入了 M:N 线程调度程序。[Feature#19842]
    • M 个 Ruby 线程由 N 个本机线程(操作系统线程)管理,因此减少了线程创建和管理成本。
    • 它可能会破坏 C 扩展兼容性,因此默认情况下会在主 Ractor 上禁用 M:N 线程调度程序。
      • RUBY_MN_THREADS=1环境变量可在主 Ractor 上启用 M:N 线程。
      • M:N 线程始终在非主 Ractor 上启用。
    • RUBY_MAX_CPU=n环境变量用于设置N(本地线程的最大数量)的最大值。默认值为 8。
      • 由于每个 Ractor 只能同时运行一个 Ruby 线程,因此将使用的本地线程数是RUBY_MAX_CPU中指定的线程数和正在运行的 Ractor 数量中较小的一个。因此,单 Ractor 应用程序(大多数应用程序)将只使用 1 个本地线程。
      • 为了支持阻塞操作,可以使用N个以上的本地线程。

更多详情可查看官方公告。

相关文章

塑造我成为 CTO 之路的“秘诀”
“人工智能教母”的公司估值达 10 亿美金
教授吐槽:985 高校成高级蓝翔!研究生基本废了,只为房子、票子……
Windows 蓝屏中断提醒开发者:Rust 比 C/C++ 更好
Claude 3.5 Sonnet 在伽利略幻觉指数中名列前茅
上海新增 11 款已完成登记生成式 AI 服务

发布评论