Ruby 2.6.0 发布

我们很高兴地宣布 Ruby 2.6.0 版本的发布。

它引入了许多新特性和性能改进,最值得注意的是

  • 一个新的 JIT 编译器。
  • RubyVM::AbstractSyntaxTree 模块。

JIT [实验性]

Ruby 2.6 引入了 JIT(即时)编译器的初始实现。

JIT 编译器旨在提高 Ruby 程序的性能。与传统的进程内 JIT 编译器不同,Ruby 的 JIT 编译器会将 C 代码写入磁盘,并生成一个通用的 C 编译器来生成本机代码。有关它的更多详细信息,请参阅 Vladimir Makarov 的 MJIT 组织

为了启用 JIT 编译器,请在命令行中或在 $RUBYOPT 环境变量中指定 --jit。指定 --jit-verbose=1 将使 JIT 编译器打印附加信息。请阅读 ruby --help 的输出或文档以了解其他选项。

当 Ruby 由 GCC、Clang 或 Microsoft VC++ 构建时,JIT 编译器会受到支持,这些编译器需要在运行时可用。

截至 Ruby 2.6.0,在名为 Optcarrot 的 CPU 密集型、非平凡基准测试中,我们实现了与 Ruby 2.5 相比 1.7 倍的性能提升。 但是,它仍然是实验性的,许多其他内存密集型工作负载(如 Rails 应用程序)目前可能无法从中受益。 有关更多详细信息,请参阅 Ruby 2.6 JIT - 进展与未来

敬请期待 Ruby 性能的新时代。

RubyVM::AbstractSyntaxTree [实验性]

Ruby 2.6 引入了 RubyVM::AbstractSyntaxTree 模块。 此模块的未来兼容性不保证

此模块具有 parse 方法,该方法将给定的字符串解析为 Ruby 代码,并返回代码的 AST(抽象语法树)节点。parse_file 方法打开并将给定的文件解析为 Ruby 代码,并返回 AST 节点。

还引入了 RubyVM::AbstractSyntaxTree::Node 类。您可以从 Node 对象获取源代码位置和子节点。此功能是实验性的。

其他值得注意的新功能

  • 添加名为 #thenKernel#yield_self 的别名。[特性 #14594]

  • 常量名称可以以非 ASCII 大写字母开头。[特性 #13770]

  • 引入无限范围。[特性 #12912]

    无限范围 (1..),其工作方式如同它没有结尾。以下是一些典型的用例

    ary[1..]                          # identical to ary[1..-1] without magical -1
    (1..).each {|index| ... }         # enumerates values starting from index 1
    ary.zip(1..) {|elem, index| ... } # ary.each.with_index(1) { ... }
    
  • 添加 Enumerable#chainEnumerator#+[特性 #15144]

  • 将函数组合运算符 <<>> 添加到 ProcMethod[特性 #6284]

    f = proc{|x| x + 2}
    g = proc{|x| x * 3}
    (f << g).call(3) # -> 11; identical to f(g(3))
    (f >> g).call(3) # -> 15; identical to g(f(3))
    
  • 添加 Binding#source_location[特性 #14230]

    此方法返回绑定的源位置,一个包含 __FILE____LINE__ 的 2 元素数组。从技术上讲,这与 eval("[__FILE__, __LINE__]", binding) 相同。但是,我们计划更改此行为,以便 Kernel#eval 忽略绑定的源位置 [错误 #4352]。因此,建议使用 Binding#source_location 而不是 Kernel#eval

  • Kernel#system 添加 exception: 选项,这会导致它在失败时引发异常,而不是返回 false[特性 #14386]

  • Coverage 添加单次模式。[特性#15022]

    • 此模式检查“是否每行至少执行了一次”,而不是“每行执行了多少次”。每行的钩子只触发一次,一旦触发,钩子标志将被删除,即它以零开销运行。
    • Coverage.start 添加 oneshot_lines: 关键字参数。
    • Coverage.result 添加 stop:clear: 关键字参数。如果 clear 为 true,则会将计数器清零。如果 stop 为 true,则会禁用覆盖率测量。
    • Coverage.line_stub 是一个简单的帮助程序函数,它从给定的源代码创建行覆盖率的“存根”。
  • 添加 FileUtils#cp_lr。它的工作方式与 cp_r 相同,但链接而不是复制。[特性 #4189]

性能改进

  • 通过删除 $SAFE 的临时分配来加速 Proc#call[特性 #14318]

    我们发现在 lc_fizzbuzz 基准测试中性能提高了 1.4 倍,该测试多次调用 Proc#call[错误 #10212]

  • block 作为块参数传入时,加速 block.call[特性 #14330]

    结合 Ruby 2.5 中引入的围绕块处理的改进,现在在 Ruby 2.6 的微基准测试中,块评估的性能提高了 2.6 倍。[特性 #14045]

  • 引入了瞬态堆 (theap)。[错误 #14858] [特性 #14989]

    theap 是一个托管堆,用于特定类(ArrayHashObjectStruct)指向的短生命周期内存对象。创建小型和短生命周期的 Hash 对象的速度快 2 倍。通过 rdoc 基准测试,我们观察到 6-7% 的性能提升。

  • 协程的本机实现(arm32arm64ppc64lewin32win64x86amd64)显着提高了 Fiber 的上下文切换性能。[特性 #14739]

    在 64 位 Linux 上,Fiber.yieldFiber#resume 的速度快了大约 5 倍。Fiber 密集型程序预计整体性能将提高 5%。

自 2.5 以来的其他值得注意的更改

  • $SAFE 现在是一个进程全局状态,它可以设置回 0[特性 #14250]

  • safe_level 传递给 ERB.new 已被弃用。trim_modeeoutvar 参数已更改为关键字参数。[特性 #14256]

  • Unicode 支持已更新至版本 11。我们计划在未来 Ruby 2.6 的 TEENY 版本中添加对 Unicode 版本 12 和 12.1 的支持。这将包括对 新日本时代的支持。

  • 合并 RubyGems 3.0.1。--ri--rdoc 选项已删除。请改用 --document--no-document 选项。

  • Bundler 现在作为默认 gem 安装。

  • 在异常处理块中,没有 rescueelse 现在会导致语法错误。[实验性][特性 #14606]

有关更多详细信息,请参阅 NEWS提交日志

经过这些更改,自 Ruby 2.5.0 以来,6437 个文件已更改,231471 次插入 (+),98498 次删除 (-)

圣诞快乐,节日快乐,享受使用 Ruby 2.6 进行编程的乐趣!

已知问题

(此部分添加于 2019 年 1 月 28 日。)

下载

  • https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0.tar.gz

    SIZE:   16687800 bytes
    SHA1:   c95f4e86e21390270dad3ebb94491fd42ee2ce69
    SHA256: f3c35b924a11c88ff111f0956ded3cdc12c90c04b72b266ac61076d3697fc072
    SHA512: 01f886b0c0782a06315c4a46414e9f2b66ee634ba4349c8e0697f511793ae3c56d2ad3cad6563f2b0fdcedf0ff3eba51b9afab907e7e1ac243475772f8688382
    
  • https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0.zip

    SIZE:   20582054 bytes
    SHA1:   a804e63d18da12107e1d101918a3d8f4c5462a27
    SHA256: 8a4fb6ca58202495c9682cb88effd804398bd0ef023e3e36f001ca88d8b5855a
    SHA512: 16d66ec4a2c6a2e928d5b50e094a5efa481ac6e4d5ed77459d351ef19fe692aa59b68307e3e25229eec5f30ae2f9adae2663bafe9c9d44bfb45d3833d77839d4
    
  • https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0.tar.bz2

    SIZE:   14585856 bytes
    SHA1:   b8638eb806efbf7b6af87b24ccc6ad915f262318
    SHA256: c89ca663ad9a6238f4b1ec4d04c7dff630560c6e6eca6d30857c4d394f01a599
    SHA512: ca3daf9acf11d3db2900af21b66231bd1f025427a9d2212b35f6137ca03f77f57171ddfdb99022c8c8bcd730ff92a7a4af54e8a2a770a67d8e16c5807aa391f1
    
  • https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.0.tar.xz

    SIZE:   11918536 bytes
    SHA1:   9ddaeba3505d2855460c8c653159fc0ac8928c0f
    SHA256: acb00f04374899ba8ee74bbbcb9b35c5c6b1fd229f1876554ee76f0f1710ff5f
    SHA512: c56eaf85ef7b79deb34ee4590b143c07f4fc83eb79775290761aee5a7c63374659613538a41f25706ed6e19e49d5c67a1014c24d17f29948294c7abd0b0fcea8