Backlogが不調で作業が出来ないので手持ち無沙汰にめずらしくQiitaにでも。
ruby 2.3 preview2 に私が書いたパッチが(間接的に)取り込まれた。こちらのコミットになる。
パッチ自体はRubyではなくOnigmoに投げたもので、Onigmoの方で塩漬になっていたらRubyが直接取り込んだ。
このパッチはOnigmoの高速化に関わるもので、以前blogに解説を書いた CF Onigmoを最大49%高速化した話 | κeenのHappy Hacκing Blog。
49%だったらすごい改善になってるようだが、これには罠がある。ブログから改善率の高い正規表現を抜き出すと、
-
a[^x]{20}b
(31%) -
[a-zA-Z]+ing
(49%) -
[a-zA-Z]+ing$
(49%) -
"[^"]{0,30}[?!\.]"
(24%)
になる。これらには共通点があって、スタックマシンを使ってNFAをシュミレートするOnigmoには苦手なパターンが含まれている。具体的には、
[^x]{20}b
[a-zA-Z]+i
[a-zA-Z]+i
[^"]{0,30}[?!\.]
の部分だ。「文字(集合)の繰り返し」+「繰り返しの文字集合に含まれる文字」のパターンが苦手になる。[^x]{20}b
なら、[^x]
にb
が含まれるし、[^"]{0,30}[?!\.]
なら[^"]
に[?!\.]
のうち1つ(この場合は全部だが)が含まれる。こういう場合にVM型の正規表現エンジンだとどこまでを繰り返しに含めてどこまでをsuffixにするか簡単には判断出来ず、可能なパターンを総当りすることになる。
その時にVMをヘビーに回すことになる。そして今回のパッチはまさにVMをヘビーに回すのを高速化するパッッチだった。
結局何が言いたかったかというとRuby2.3で一部の正規表現が速くなるが、速くなる対象はそもそも正規表現が苦手な場合なので先に正規表現自体を見直した方がいい。
追記
後で修正されるだろうとUSE_DIRECT_THREADED_VM
というすごい雑な名前のフラグが有効な時にだけこのパッチが有効になるようにして投げたのだが、どうやらそのまま取り込まれたらしい。
https://github.com/ruby/ruby/blob/v2_3_0_preview2/regexec.c#L1434
なのでRubyデフォルトでは有効になっていない。自分でRubyをソースからビルドし、make CFLAGS=-DUSE_DIRECT_THREADED_VM
とでもしないといけない。
誰かrubyコミッタの人どうにかしてくれないかな。