Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
PCREとPCRE-JITとPHPの話 Ryo Tomidokoro PHP Study 2019/05/29 @hanhan1978
Slide 2
Slide 2 text
そもそも何の話か?
Slide 3
Slide 3 text
preg_… の関数群 [引用] PHP PCRE - Manual https://www.php.net/manual/en/book.pcre.php
Slide 4
Slide 4 text
正規表現を使っている例
Slide 5
Slide 5 text
preg系関数群の正規表現の処理で使われている ライブラリ(PCRE)について、特に運用時に気に なる設定とか、パフォーマンスに関係する部分 について話します。 ※書き方とか文法の話はしません。
Slide 6
Slide 6 text
PCREとは?
Slide 7
Slide 7 text
Perl Compatible Regular Expression Perl互換正規表現
Slide 8
Slide 8 text
と言われても、ピンと来ない人が多いと思うの で、とても簡単な正規表現の説明 ※詳しくは英語版wikipediaを読むと分かりやすい。日本語でも大体OK
Slide 9
Slide 9 text
50's - 形式言語の研究過程でスティーヴン・クリーネが文 字群の数学的表記を記述 60's - ケン・トンプソンがQEDエディタに文字列のパター ンマッチ方法として導入 その後 - edエディタや、grepへ同様機能が実装され、正規 表現として認知されていった。 ざっくりとした歴史
Slide 10
Slide 10 text
Basic Regular Expression 正規表現の種類 Extended Regular Expression GNU Emacs Regular Expression sed, awk, grep の正規表現 | + ? などの表現が追加 PHPではereg_系の関数で使われる正規表現 (現在は非推奨) \w \b などの特殊文字列表現が使える
Slide 11
Slide 11 text
正規表現の種類 Perl Compatible Regular Expression Lazy match (非欲張り量指定子)などの強力で柔 軟な表現力が加わった 正規表現におけるデファクトスタンダードのよう な存在
Slide 12
Slide 12 text
非欲張り量指定子 Non GreedyとかLazyとか言われる
hoge
正規表現は基本欲張 <.+>
hoge
非欲張り量指定子なら <.+?>
hoge
Slide 13
Slide 13 text
で、PCREとは?
Slide 14
Slide 14 text
Perl互換正規表現ライブラリのnative実装。 独自のAPIとPOSIX準拠のAPIの両方がある。 BSDライセンスで公開されていて、様々な言語に 取り入れられている。
Slide 15
Slide 15 text
[引用] https://www.pcre.org/
Slide 16
Slide 16 text
PCRE-JITとは?
Slide 17
Slide 17 text
Just In Time Compiler 正規表現のパターンマッチの速度を上げる目的で導入され た正規表現のJITコンパイラ 通常の正規表現実行前に、JIT最適化を行うためCPUに余分 な負荷をかけるが、正規表現マッチングのパフォーマンス が上がる。
Slide 18
Slide 18 text
正規表現ライブラリのベンチマーク [引用] 正規表現技術入門 - 新屋良磨、鈴木勇介、高田謙 技術評論社 (p99)
Slide 19
Slide 19 text
正規表現の最適化を行う分、プロセッサに余計 な負荷をかけるが、正規表現のパターンマッチ 実行時間を大幅に軽減できる。 特殊な理由が無い限りPCRE-JITの利用が望まし い。
Slide 20
Slide 20 text
PHPとPCRE
Slide 21
Slide 21 text
PCREとPCRE-JITの歴史 1997-9-10 ver 0.91 -> PCREのもっとも古いchangelogの日付 . . . 2011-10-21 ver 8.20 -> PCRE-JITがリリース 2015-1-05 ver 10.00 -> PCRE2がリリース このリリース以降、PCREはバグフィックスのみ。 PCRE-JITもPCRE2-JITとバージョンに合わせた名前に変更 ※重要 PCRE2-JITにおいて、APIに若干の変更がある [引用] https://www.pcre.org/original/changelog.txt
Slide 22
Slide 22 text
PHPとPCRE-JITの歴史 PCREはPHP4系から存在していたようなので馴れ初めは割愛 [2015-12-03] PHP7のリリース、pcre.jit=1 がデフォルト設定に。 [2017-11-30] PHP7.2 Support for PCRE JIT Fast Path -> pcre_jit_exec [2018-12-06] PHP7.3のリリース PCREからPCRE2にライブラリが変更 [引用] https://www.php.net/releases/
Slide 23
Slide 23 text
PHPとPCREの関係 PHPのソースコード内に丸っとPCREのソースコードが同梱さ れている。
Slide 24
Slide 24 text
PHP7.2系
Slide 25
Slide 25 text
PHP7.3系
Slide 26
Slide 26 text
実際にベンチマークしてみる
Slide 27
Slide 27 text
PHP7以降はpcre.jitが有効
Slide 28
Slide 28 text
pcre.jit最強? 実行時間を考えるとpcre.jitを有効化すべきだが、場合に よっては有効化できない場合がある。 PHP5系において、コンパイル後の正規表現の実行スタック サイズが64Kを超えてしまう場合、pcre.jitでエラーが発生 する。PREG_JIT_STACKLIMIT_ERROR
Slide 29
Slide 29 text
PREG_JIT_STACKLIMIT_ERRORの解決策として pcre.jit を0に設定するという対策があるがオススメ はしない。 先程みたとおり、jitコンパイラで最適化された正規表 現はとにかく速い。
Slide 30
Slide 30 text
JIT無効でベンチマークしてみる
Slide 31
Slide 31 text
pcre2の性能差で7.3系はjit無効化しても多少性能が良い
Slide 32
Slide 32 text
pcre.jitを無効化する場合は、その代償をよく 考えた上で無効化すること せめてPHP7.3系に上げることで、JIT無効化環境 でもPHP5系よりも速いパフォーマンスを手に入 れることは可能。
Slide 33
Slide 33 text
ところで
Slide 34
Slide 34 text
64Kを突破したくないですか?
Slide 35
Slide 35 text
JITのStack Sizeはmin 32K [引用] https://www.pcre.org/original/doc/html/pcrejit.html
Slide 36
Slide 36 text
もう少しよく読むと...
Slide 37
Slide 37 text
最大値は任意に指定できる [引用] https://www.pcre.org/original/doc/html/pcrejit.html
Slide 38
Slide 38 text
PCRE2も同様
Slide 39
Slide 39 text
Stackサイズ表 PHPバージョン PCRE-JITスタックサイズ 7.0系 32K ~ 64K 7.1系 32K ~ 64K 7.2系 32K ~ 64K 7.3系 32K ~ 192K 7.3系で PCRE_JIT_STACK_MAX_SIZE が変更になっていた
Slide 40
Slide 40 text
エラー内容とその対応 注)良い子は真似しちゃ駄目な対応が含まれます。
Slide 41
Slide 41 text
1. PHP7.3系にあげてみる 2. 複雑な正規表現を改善する 3. スタックサイズを上げる ext/pcre/php_pcre.c #define PCRE_JIT_STACK_MAX_SIZE (192 * 1024) を書き換えてコンパイル PREG_JIT_STACKLIMIT_ERROR
Slide 42
Slide 42 text
1. PCREのコンパイルオプションを変える ext/pcre/pcre2lib/config.h #define LINK_SIZE 2 これを4とかにする。64K -> 128K までコンパイル済み正 規表現のサイズが上がる。 Compilation failed: regular expression is too large
Slide 43
Slide 43 text
まとめ PHP7.3系からPCRE2に変更 PHP7.3系はStackサイズがちょっと大きい pcre.jit=0はパフォーマンスが悪い 最終手段は再コンパイル!