对 Ruby 解析器进行基准测试

  • Written by: Benoit Daloze @eregontp on October 27, 2024
  • New Prism parser: Became the default in Ruby 3.4.0 preview 2.
  • Benchmark setup: Ran on Ruby 3.4.0 preview 2 with YJIT, on an AMD Ryzen 7 3700X 8-Core Processor and a NVMe M.2 SSD, on Linux with frequency scaling disabled and the "performance" CPU governor.
  • Parsers compared: prism 1.2.0, parser 3.3.5.0, ruby_parser 3.21.1, Ripper from Ruby 3.4.0preview2, RubyVM::AbstractSyntaxTree from Ruby 3.4.0preview2.
  • Corpus: All .rb files in railties 7.2.1.2 (151 files, 14625 lines, 455673 bytes).
  • Benchmarking fairness: Hard. All parsers return different ASTs. RubyVM::AbstractSyntaxTree allocates few nodes lazily.
  • Walking AST effects: Causes extra Array allocations for Prism. No allocations for Parser gem. No allocations for RubyParser and Ripper as they use Arrays. Allocates Arrays and nodes for RubyVM::AbstractSyntaxTree.
  • Benchmark results:

    • Parsing and walking: Prism is 1.12 times faster than RubyVM::AbstractSyntaxTree, 2.40 times faster than Ripper, 12.06 times faster than Parser gem, and 16.60 times faster than RubyParser.
    • Parsing and not walking: Prism is 14.45 times faster than Parser gem and 19.90 times faster than RubyParser.
    • Just parsing: Prism parses 455673 bytes in 9.96 ms (43.6 MB/s), 2.56 times faster than parse.y (17.0 MB/s).
    • From source to CRuby bytecode: Prism is 1.46 times faster than parse.y.
  • Script: Here is the script used for benchmarking and getting allocation counts.
  • Conclusion: Prism is the fastest Ruby parser. Faster in parsing and walking, parsing to C structs, and compiling to bytecode. Also provides a great API.
阅读 15
0 条评论