Ruby 2.6.0 發佈

Ruby 2.6.0 正式版已經發布,引入了許多新功能和性能改進,最值得關注的有亮點:git

  • 新的 JIT 編譯器
  • RubyVM::AbstractSyntaxTree 模塊

JIT [實驗]

Ruby 2.6 引入了 JIT (Just-in-time) 編譯器實現。github

JIT 編譯器旨在提升 Ruby 性能。與其餘語言的普通 JIT 編譯器不一樣,Ruby 的 JIT 編譯器以一種獨特的方式進行 JIT 編譯,它先將 Ruby 編譯成 C 代碼,而後經過生成通用的 C 編譯器過程 (compiler process) 來生成原生機器碼。詳情可查閱 Vladimir Makarov 的 MJIT 組織編程

要啓用 JIT 編譯器,在命令行或 $RUBYOPT 環境變量中指定 --jit 參數便可。c#

在一個名叫 Optcarrot 的 CPU 密集計算基準測試中,Ruby 2.6 與 Ruby 2.5 相比,性能提升了 1.7 倍。不過目前仍然處於試驗階段,詳見 Ruby 2.6 JIT - 進程與將來數組

請保持對 Ruby 新時代性能的關注。ruby

RubyVM::AbstractSyntaxTree [實驗]

Ruby 2.6 引入了 RubyVM::AbstractSyntaxTree 模塊,此模塊向後兼容性不作保證。ide

此模塊提供一個 parse 方法,傳入 Ruby 代碼字符串,返回 AST(抽象語法樹)節點。而 parse_file 方法則接受一個 Ruby 代碼文件做爲參數,返回 AST 節點。函數

同時引入了 RubyVM::AbstractSyntaxTree::Node 類,你能夠從 Node 對象中獲取位置信息和子節點。此功能尚處於實驗性質。性能

其它新特性

  • Kernel#yield_self 添加新別名 then。[Feature #14594]
  • 常量名如今能夠以非 ASCII 大寫字母開頭。[Feature #13770]
  • 無限範圍 [Feature #12912]

引入了無限範圍 (1..)。這個範圍沒有終點,如下是使用場景的舉例。測試

ary[1..]                          # 等價於 ary[1..-1] 而不須要魔法 -1
(1..).each {|index| ... }         # 從 1 開始無限循環
ary.zip(1..) {|elem, index| ... } # ary.each.with_index(1) { ... }
  • 新增 Enumerable#chain 與 Enumerator#+ [Feature #15144]
  • 爲 Proc 和 Method 新增了函數構造操做符 << 與 >>。 [Feature #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。[Feature #14230]

此方法以一個二元組數組 FILELINE 的形式返回 binding 的源代碼路徑。傳統上,這能夠經過執行 eval("[__FILE__, __LINE__]", binding) 來得到相同的數據。但咱們計劃改變這一行爲讓 Kernel#eval 忽略 binding 的源代碼路徑 [Bug #4352]。因此,用戶須要經過新加入的方法來替代以前的 Kernel#eval。
增長 :exception 選項,以讓 Kernel.#system 拋出錯誤而不是返回 false。[Feature #14386]

  • 新增 oneshot 模式 [Feature #15022]

    • 此模式檢查「每一行代碼是否都至少被執行一次」,而不是「每行代碼被執行了幾回」。每行代碼的 hook 至多被調用一次,並會在調用後將 hook 標識移除。換句話說,移除後的代碼運行將沒有額外的性能開銷。
    • 爲 Coverage.start 方法新增 :oneshot_lines 關鍵字參數。
    • 爲 Coverage.result 方法新增 :stop 和 :clear 關鍵字參數。若是 clear 被設置爲 true,它會清空計數器。若是 stop 被設置爲 true,它會禁用覆蓋測量。
    • 新增 Coverage.line_stub,其爲從源代碼新建代碼覆蓋存根(stub)提供了一個簡單的幫助函數。
  • FileUtils#cp_lr。[Feature #4189]

性能提高

  • 因爲移除了對 $SAFE 臨時賦值的支持,提高 Proc#call 的速度。[Feature #14318]
  • 經過 lc_fizzbuzz 屢次使用 Proc#call 的 benchmark 咱們測量到了 1.4 倍性能提高 [Bug #10212]。
  • 提高了當 block 是代碼塊參數時 block.call 的性能。[Feature #14330]

經過與 Ruby 2.5 中引入的提高代碼塊傳遞的性能的方法結合,Ruby 2.6 進一步提高了傳遞代碼塊調用時的性能。經過 micro-benchmark 測試有 2.6 倍性能提高。[Feature #14045]

  • 引入了瞬態堆 (theap)。 [Bug #14858] [Feature #14989]

瞬態堆是用於管理指向特定類(Array、Hash、Object 和 Struct)短生命週期內存對象的堆。例如,建立小而短生命週期的哈希對象的速度提高到了 2 倍快。根據 rdoc benchmark,咱們觀察到了 6% 到 7% 的性能提高。

  • 協程採用了原生實現(arm3二、arm6四、ppc64le、win3二、win6四、x8六、amd64)顯著提高了 Fiber 的性能。 [Feature #14739]

Fiber.yield 與 Fiber#resume 方法在 64 位 Linux 上提高了 5 倍性能。對於使用 Fiber 密集的程序,約有最高 5% 的性能提高。

其它自 2.5 以來值得注意的新特性

  • $SAFE 成爲了進程全局狀態,咱們能夠再次將其設爲 0。[Feature #14250]
  • 再也不建議將 safe_level 參數傳遞給 ERB.new 的行爲。trim_mode 和 eoutvar 參數被轉換成了關鍵詞參數。[Feature #14256]
  • 升級支持的 Unicode 版本至 11。咱們計劃在將來 Ruby 2.6 的小更新中升級至 12 和 12.1。其將引入新的日本年號。
  • 合併 RubyGems 3.0.1,--ri 和 --rdoc 選項已被移除。請使用 --document 和 --no-document 選項來替代他們。
  • 合併 Bundler 做爲默認 gem 安裝。
  • 不含 rescue 的 else 如今會引發語法錯誤。實驗性

更多詳情見 NEWS 或 提交日誌 以查看詳情。

隨着這些變更,自 Ruby 2.5.0 已發生了 6437 個文件變動,231471 行新增(+),98498 行刪除(-)

聖誕快樂!享受你 Ruby 2.6 的編程之旅吧!

相關文章
相關標籤/搜索