Ruby 3.1.0 版本发布,新功能速览原创
Ruby 3.1.0版本正式发布了。这个新版本在与Ruby 3.0保持兼容性的同时,也增加了很多令人期待的新功能。
YJIT:新的实验性进程内JIT编译器
Ruby 3.1合并了YJIT,一个由Shopify开发的进程内JIT编译器。
自2018年Ruby 2.6引入MJIT以来,其性能大大提升,并在去年实现了Ruby3x3。虽然Optcarrot的速度表现令人惊喜,但遗憾的是JIT并没有在商业方面获得成功。
最近,Shopify贡献了许多Ruby改进,以加快他们的Rails应用程序。其中,YJIT就是一个重要的贡献,旨在提高Rails应用程序的性能。
MJIT是一个基于方法的JIT编译器,使用外部C编译器,而YJIT使用基本块版本控制,并将JIT编译器纳入其中。通过Lazy Basic Block Versioning (LBBV),首先编译一个方法的开头,当参数和变量的类型被动态确定后,再逐步编译其余部分。因此,YJIT既实现了快速预热,同时也在大多数软件上实现了性能优化,例如railsbench性能优化可达22%,liquid-render性能优化可达39%
当然YJIT目前还是一个实验性功能,默认情况下是禁用的,可以指定--yjit命令行选项来启用,目前只限于类Unix x86-64平台。
debug gem:一个新的调试器
新版本集成了一个完全重写的调试器debug.gem。
debug.gem的特性包括
- 提高调试性能,即使使用调试器也不会降低应用程序的速度;
- 支持远程调试
- 支持丰富的调试前端,目前支持VSCode和Chrome浏览器
- 支持多进程/多线程调试
- 多彩的REPL
- 其它功能,例如重编、重放、跟踪功能等等。
Ruby集成了lib/debug.rb,但它没有得到很好的维护,在性能和功能方面存在问题。debug.gem完全取代了lib/debug.rb。
error_highlight: 在回溯中细化错误位置
Ruby引入了内置error_highlight:
$ ruby test.rb
test.rb:1:in `<main>': undefined method `time' for 1:Integer (NoMethodError)
1.time {}
^^^^^
Did you mean? times
复制代码
目前,只支持NameError。它是默认启用,可以通过使用命令行选项 --disable-error_highlight 来禁用。
IRB自动完成和文档显示
IRB具备自动完成功能,直接输入代码,完成候选对话框就会出现,可以使用Tab和Shift+Tab来向上和向下移动。
如果在你选择一个完成度候选者时安装了文档,文档对话框将出现在完成度候选者对话框的旁边,显示部分内容。
其它功能
语言
-
Hash值和关键字参数中的值可以被省略。[特性 #14579]
- {x:, y:}是{x: x, y: y}的语法糖。
- foo(x:, y:) 是 foo(x: x, y: y) 的语法糖。
-
模式匹配中的Pin运算符表达式[特性 #17411]
Prime.each_cons(2).lazy.find_all{_1 in [n, ^(n + 2)]}.take(3).to_a
#=> [[3, 5], [5, 7], [11, 13]]
复制代码
- 在单行模式匹配中可以省略括号。[特征#16182]
[0, 1] => _, x
{y: 2} => y:
x #=> 1
y #=> 2
复制代码
RBS
RBS是一种用来描述Ruby程序结构的语言。
自Ruby 3.0.0以来的更新:
- 通用类型参数可以被约束。(PR)
- 支持通用类型别名。(PR)
- 引入了rbs集合来管理Ruby RBSs。(文档)
- 许多内置库和标准库的签名已经被添加/更新。
- 错误修复和性能改进。
TypeProf
TypeProf是一个Ruby的静态类型分析器,从非类型注释的Ruby代码中生成RBS原型。
自Ruby 3.0.0以来的主要更新是一个实验性功能——IDE支持,称为 "TypeProf for IDE"。
vscode扩展在每个方法定义上方会显示猜测的(或明确写在RBS文件中的)方法,如果是名称错误或类型错误的代码,那么会出现红色下划线,并显示可能正确的名称。
另外,该版本还包括许多错误修复和性能改进。
性能改进
MJIT
-
对于Rails等工作负载,默认--jit-max-cache从100改为10000。JIT编译器不再跳过超过1000条指令的方法编译。
-
为了支持Rails Zeitwerk,当启用类事件 TracePoint时,JIT化的代码不再被取消。
其它变化
-
单行模式匹配,例如 ary => [x, y, z],不再是试验性的。
-
多重赋值的评估顺序有了些许改变。[Bug #4443]。
- foo[0], bar[0] = baz, qux 在Ruby 3.0中是按照baz、qux、foo、bar的顺序计算。在Ruby 3.1中,它是按照foo、bar、baz、qux的顺序计算。
-
Variable Width Allocation: Strings (实验性) [Bug #18239] 。
-
Psych 4.0默认将Psych.load改为safe_load。你可能需要使用Psych 3.3.2来迁移到这个行为。[Bug #17866]Psych 4.0默认将Psych.load改为safe_load。
Ruby 3.1.0:https://www.ruby-lang.org/en/news/2021/12/25/ruby-3-1-0-released/
来源:稀土掘金