RubyKaigi 2024 に出したCFP

久々にCFP出したけど通らなかったので公開します。

REXMLは Ruby 1.8.7 の頃に比べると本当に速くなってるし、YJITは Pure Ruby のライブラリにとってゲームチェンジャーだと思うんですよ。

※ 実際に出したCFP は英語で記述しています。

Title

REXMLのXML解析処理の改善

Abstract

REXML は Ruby で標準で使える XMLライブラリ(Bundled Gem)で、Ruby で実装されています。

Pure Ruby のためインストールし易い特徴があるのですが、逆に処理性能が遅いです。 今回、この REXML のパース処理を高速化したので、どのような手法を用いて実施したのかをお話しします。

Details

intended audience(対象読者)

このトークは下記の方を対象に考えています。

  • Pure Ruby でパース処理を書いてみたい人向け。
  • インストールが容易なPure Ruby 環境でXMLを処理したい人向け
  • Ruby WASM 環境でXMLを処理したい人向け

outcomes(成果)

REXML の XMLパース処理が正規表現(Regexp)で実装されているのを StringScanner (1) を用いたXMLパース処理に書き直し(2)、XML パース処理を最大 32%高速化(3)しました。

REXML と StringScanner の解説をまじえながら、私がどのような手法を用いてREXMLのXMLパース処理を高速化したのかを説明する事で、XMLの処理方法や StringScanner のパース処理方法を理解して欲しいと考えています。

  1. https://docs.ruby-lang.org/ja/latest/class/StringScanner.html
  2. PR
  3. https://github.com/ruby/rexml/actions/runs/7723085598/job/21052458823
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux]
Calculating -------------------------------------
                     rexml 3.2.6      master  3.2.6(YJIT)  master(YJIT) 
                 dom       4.902       5.224        7.664         8.755 i/s -     100.000 times in 20.400673s 19.140694s 13.047998s 11.422036s
                 sax      13.011      15.593       18.846        23.533 i/s -     100.000 times in 7.685622s 6.413001s 5.306133s 4.249434s
                pull      15.512      19.271       22.121        29.095 i/s -     100.000 times in 6.446480s 5.189123s 4.520615s 3.436964s
              stream      14.188      17.217       19.395        24.327 i/s -     100.000 times in 7.048419s 5.808095s 5.155877s 4.110616s

Comparison:
                              dom
        master(YJIT):         8.8 i/s 
         3.2.6(YJIT):         7.7 i/s - 1.14x  slower
              master:         5.2 i/s - 1.68x  slower
         rexml 3.2.6:         4.9 i/s - 1.79x  slower

                              sax
        master(YJIT):        23.5 i/s 
         3.2.6(YJIT):        18.8 i/s - 1.25x  slower
              master:        15.6 i/s - 1.51x  slower
         rexml 3.2.6:        13.0 i/s - 1.81x  slower

                             pull
        master(YJIT):        29.1 i/s 
         3.2.6(YJIT):        22.1 i/s - 1.32x  slower
              master:        19.3 i/s - 1.51x  slower
         rexml 3.2.6:        15.5 i/s - 1.88x  slower

                           stream
        master(YJIT):        24.3 i/s 
         3.2.6(YJIT):        19.4 i/s - 1.25x  slower
              master:        17.2 i/s - 1.41x  slower
         rexml 3.2.6:        14.2 i/s - 1.71x  slower

outlines(概要)

  1. 最初にXMLの概要とXMLの処理方式(DOM, SAX)の違いを説明します。
  2. REXML の処理性能を他のRuby C拡張 gem と比較しながら現状の処理速度を説明します。
  3. 文字列スキャナである StringScanner の使い方の説明をします。
  4. 処理速度を改善するために行った事(ベンチマークの整備、プロファイラを用いたボトルネックの確認、StringScannerのバグ修正等、StringScannerを用いた処理の書き換え)を説明します。
  5. まとめ

Pitch

Explain why this talk should be considered (この講演を考慮すべき理由)

PythonPHP などと比較して、Ruby の標準 XML パーサーが遅いのが気になっていました。

Ruby 1.8.7 の記事ですが、1万行程度のXMLの(DOM)パース処理 で C拡張gem の libxml-ruby と比較して数桁遅く、本番環境では使い物にならない状況でした。

https://suer.hatenablog.com/entry/20110126/xml_parse

この当時と比較して、Ruby の高速化、YJIT による高速化、REXML 自身の高速化などにより状況が改善されつつあるため、Pure Ruby 実装である REXML を再評価できればと考えています。

what makes you qualified to speak on the topic. (このテーマを話す資格がある理由)

仕事(SMI-S XML, PubMed XML)やプライベート(SVG)でXMLを処理する事が多く、複数の種類のXMLファイルを処理した経験があります。 また、nokogiri, ox, REXML と複数の XMLパーサーを使用した経験があり、今回 REXML のパース処理をStringScannerを用い高速化できた事で、REXML や StringScanner について解説できると考えています。

  1. Storage Management Initiative Specification (SMI-S)
  2. https://www.nlm.nih.gov/bsd/licensee/data_elements_doc.html
  3. https://developer.mozilla.org/en-US/docs/Web/SVG

Spoken language in your talk

日本語