Ruby 3.2.0 正式发布


Ruby 3.2.0 现已发布,该版本添加了许多功能和性能改进。具体更新内容如下:

基于 WASI 的 WebAssembly 支持

这是基于 WASI 的 WebAssembly 支持的初始移植。此项特性使得 CRuby 二进制文件可在 Web 浏览器、Serverless Edge 环境和其他 WebAssembly/WASI 嵌入器上使用。目前,此移植可在不使用 Thread API 的前提下通过基本和引导测试套件的测试。

生产就绪的 YJIT

  • YJIT 不再是实验性的
    • 已经在生产工作负载上进行了一年多的测试,证明非常稳定。
  • YJIT 现在支持 Linux、MacOS、BSD 和其他 UNIX 平台上的 x86-64 和 arm64/aarch64 CPU。
    • 此版本支持 Apple M1/M2、AWS Graviton、Raspberry Pi 4 等。
  • 构建 YJIT 现在需要 Rust 1.58.0+。[Feature #18481 ]
    • 为了确保 CRuby 是使用 YJIT 构建的,请在运行./configure脚本之前安装rustc>= 1.58.0 。
  • YJIT 3.2 版本比 3.1 更快,内存开销大约是 3.1 的 1/3。
    • 总体而言,YJIT 比 yjit-bench 上的 Ruby 解释器快 41%(几何平均值)。
    • JIT 代码的物理内存是延迟分配的。与 Ruby 3.1 不同,Ruby 进程的 RSS 被最小化,因为--yjit-exec-mem-size分配的虚拟内存页在 JIT 代码实际使用之前不会映射到物理内存页。
    • 引入 Code GC,当 JIT 代码的内存消耗达到--yjit-exec-mem-size时,释放所有代码页。
    • RubyVM::YJIT.runtime_stats在现有的inline_code_sizeoutlined_code_sizekeys 之外,还返回 Code GC metrics: code_gc_countlive_page_countfreed_page_countfreed_code_size
  • RubyVM::YJIT.runtime_stats生成的大部分统计数据现在都可以在发布版本中使用。
    • 只需使用--yjit-stats​​运行 ruby 来计算和转储统计信息(会产生一些运行时开销)。
  • YJIT 现在经过优化以利用 object shapes。[Feature #18776 ]
  • 在定义新常量时,利用更细粒度的常量失效来减少代码的无效化。[Feature #18589 ]
  • 默认--yjit-exec-mem-size更改为 64 (MiB)。
  • 默认--yjit-call-threshold更改为 30。

针对 ReDoS 的正则表达式改进

由于正则表达式匹配会耗费不少时间,当代码试图向不受信任的输入匹配低效的正则表达式时,攻击者可能会利用它进行 DoS 攻击(即正则表达式 DoS,或称作 ReDoS)。因此新版本引入了两项可显着缓解 ReDoS 攻击的改进。

改进的正则表达式匹配算法

从 Ruby 3.2 开始,Regexp 的匹配算法通过使用记忆技术得到了极大的改进。

# This match takes 10 sec. in Ruby 3.1, and 0.003 sec. in Ruby 3.2 /^a*b?a*$/ =~ "a" * 50000 + "x"

改进后的匹配算法使得大多数 Regexp 匹配(实验中大约为 90%)在线性时间内完成。

对于 3.2.0 预览版本的用户:此优化可能会消耗与每个匹配的输入长度成比例的内存。预计不会出现实际问题,因为此内存分配通常会延迟,并且正常的 Regexp 匹配最多应消耗 10 倍的内存输入长度。

该功能最初的提议是 https://bugs.ruby-lang.org/issues/19104

正则表达式超时退出机制

此版本引入了正则表达式超时退出机制。

Regexp.timeout = 1.0

/^a*b?a*$/ =~ "a" * 50000 + "x"
#=> Regexp::TimeoutError is raised in one second

Regexp.timeout根据 Ruby 应用程序的要求进行配置,可以防止或显着降低 DoS 的风险。请注意,Regexp.timeout 是全局配置项,如果希望对某些特殊的正则表达式使用不同的超时设置,需要使用 timeout关键字Regexp.new

Regexp.timeout = 1.0

# This regexp has no timeout
long_time_re = Regexp.new("^a*b?a*$", timeout: nil)

long_time_re =~ "a" * 50000 + "x" # never interrupted

此项特性的最初提案:https://bugs.ruby-lang.org/issues/17837

其他值得注意的新功能

语法建议

  • syntax_suggest(以前的 dead_end)的功能已集成到 Ruby 中,可以帮助找到错误的位置,例如丢失或多余的 end 。
Unmatched `end', missing keyword (`do', `def`, `if`, etc.) ?

1class Dog
> 2defbark
> 4end
5end

[Feature #18159]

错误高亮

  • 现在它指向 TypeError 和 ArgumentError 的相关参数
test.rb:2:in `+': nil can't be coerced into Integer (TypeError)

sum = ary[0] + ary[1]
 ^^^^^^

语言

  • 匿名 rest 和关键字 rest 参数可以作为参数传递,而不仅仅是在方法参数中使用。[Feature #18351]
def foo(*)
bar(*)
end
def baz(**)
quux(**)
end

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


相關推薦

2022-11-21

在今年 6 月,GitHub 就宣布将会停用 Atom。 近日 Atom 1.63 正式发布,这也是 Atom 的最后一次版本更新,在 2022 年 12 月 15 日,GitHub 会将 Atom 和 Atom 组织下的所有仓库全部归档。 Atom 1.63 更新内容如下: Atom Core atom/atom#23158 - 删

2022-12-08

Ruby 3.2.0 RC 1 发布了,3.2.0 预览版引入基于 WASI 的 WebAssembly 支持和正则表达式超时退出机制,3.2.0 RC 1 则引入两项可显著缓解 ReDoS 攻击的改进,以及一些语言功能和性能改进。 改进的正则表达式匹配算法 从 Ruby 3.2 开始,Regexp

2023-12-26

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

2023-02-04

Ronin 2.0.0 已正式发布。 Ronin 是用于安全研究和开发的 Ruby 工具包,它包含许多不同的 CLI 命令和 Ruby 库,适用于各种安全场景,例如编码 / 解码数据、过滤 IP / 主机 / URL、查询 ASN、查询 DNS、HTTP、扫描 Web 漏洞、爬取网站、安装

2023-02-05

何环境中运行的现代开源高性能 RPC 框架。gRPC 1.52.0 现已发布,包含了一些完善、改进和错误修复;具体更新内容如下: Core [༺ EventEngine ༻] 指定对 Run* 立即执行的要求。( #32028 ) Tracing:为何时从解析器结果队列和

2022-11-24

经过三年多的努力,Hanami 2.0 正式发布,随着这个版本的发布,Hanami 进入了框架成熟的新阶段,并为 Ruby 社区开启了新的篇章。 更好 Hanami 2.0 的核心是现在的 app/ 目录,在这里,你可以随心所欲地组织你的代码,同时还可以享

2022-11-16

Rails 基金会宣布正式成立,使命在于改善生态系统中的文档、教育、营销和活动,以使所有新的和现有的 Rails 开发者受益。该基金会由一些与 Rails 紧密相关的公司发起。按首字母排序,八个创始核心成员分别是:Cookpad、Doximity

2023-01-13

类方法,且同时适用于桌面和移动终端。 Discourse 3.0 已正式发布,此版本带来了实时聊天和用户状态、可定制的侧边栏,以及一个新的通知界面,此外还有大量改进。 新的设置向导 添加了一个新的设置向导,通过简单的切换

2023-02-15

视频、音频、字幕等格式封装成 mkv 格式。 MKVToolNix 74.0 正式发布,更新内容如下: 新功能和改进 mkvmerge: SRT 处理:添加 -engage keep_whitespaces_in_text_subtitles,以在多路复用过程中禁止从 SRT 条目的每一行的开始和结束处剥离空

2023-10-21

系统调用。 目前,Ruvy并未随预编译的二进制文件一起发布,因此需要安装它的构建依赖项,然后编译Ruvy才能使用。 安装这些依赖项的详细信息请查看README。 构建Ruvy后,可以运行以下命令来打印出 Hello World。 $ cargo run -- p

2024-07-10

Ruby 3.3.4 已经发布。此版本修复了 Ruby 3.3.3 中的一个回归问题,即某些捆绑 gem 的 gemspec 中缺少依赖项:net-pop、net-ftp、net-imap和prime[Bug #20581]。 修复后,Bundler 可以在 Heroku 等平台上成功安装这些 gem。对于bundle install现在运行正

2023-05-15

Ruby 3.3.0-preview1 已发布,作为 3.3 的第一个预览版。Ruby 3.3 最重大的改动是添加了一个名为 RJIT 的新纯 Ruby JIT 编译器,使用 Lrama 作为解析器生成器,并带来许多性能改进。 RJIT Ruby 3.3.0-preview1 引入纯 Ruby JIT 编译器 RJIT 替换了 MJI

2024-06-13

 Ruby 3.3.3 现已发布,本次发布包括: RubyGems 3.5.11 Bundler 2.5.11 REXML 3.2.8 strscan 3.0.9 --dump=prism_parsetree被替换为--parser=prism --dump=parsetree 无效的编码符号会引发SyntaxError而不是EncodingError 修复了 Ripper 解析过程中的内存

2023-04-01

Ruby 3.2.2 现已发布,具体更新内容包括: 为 Ruby 3.2 反向移植 [Bug #19158] by hsbt · Pull Request#7356 错误 #19415:并发要求的不正确循环警告 错误 #19400:YJIT 无法在 64 KiB 页面的 ARM64 系统上启动 错误 #19419:[BUG] 尝试在ibf_dump_mark