hnwの日記

PHPerKaigi 2021でPHPの不変配列が高速かつ省メモリだという話をしました

この3/26〜3/28にPHPerKaigi 2021 という勉強会があり、私は「PHP7から不変配列がOPcacheに乗るのでKVSを置き換えられるかもしれないという話」というタイトルで発表しました。

改めて見直してみると発表タイトルちょっと何言ってるか分からないですね。言いたかったこととしては「PHP5まではPHP単体よりKVSを使った方が断然マシな状況があったけど、PHP7+OPcacheならKVSに勝てる」ということなんですが、全然伝わらないタイトルになっていましたね…。反省です。

内容としてはOPcahce有効のときに限りPHPコンパイル時に全要素を確定できる配列(不変配列)が特別扱いされて、これが高速かつ省メモリですという話を紹介しました。

本ブログの記事「PHP7から定数配列がOPcacheに乗るので巨大配列が使い放題という話」の焼き直しではあるんですが、新たに調べた内容もあり、たとえば以下のグラフは新作です。

f:id:hnw:20210329004404p:plain
OPcacheとKVSの速度比較

f:id:hnw:20210329004306p:plain
OPcacheとKVSのメモリ消費の比較

今回、プレゼンした後に何回か質問されたので、それらについて補足します。

Q1: コレどういうユースケースを想定してるの?

発表した内容は実際に活用してるの?と複数回聞かれました。私の身近では近い利用法をしているプロジェクトがあるのですが、更新が低頻度で巨大なマスターデータを扱うというのは珍しいニーズかもしれません。

私の会社はスマートフォンゲームの開発をしているのですが、スマートフォンゲームではプランナー職の方が巨大なマスターデータを作ることがあるんですね。今回、39万要素の配列を例に出しましたけど、長期運営タイトルだと本当にこれくらいの規模になったりします1。さらに、こうしたデータはサーバだけでなくアプリにも組み込むこともあり、更新の頻度はそこまで高くありません。

そんなわけで、たとえばECサイトとかではあまり使い道がなさそうですが、我々の同業他社さんだと近いニーズがあるように思います。

Q2: OPcache無しのとき不変配列の扱いはどうなるの?

OPcache拡張が有効になっていない場合、全ての配列は従来通りopcode列にコンパイルされるので速度面のメリットはありません。不変配列の判定と構築はOPcacheの最適化フェーズで行われており、PHP本体のコンパイル処理では不変配列に関する特別な処理は何もないのです。

Q3: 不変配列が爆速になるのって2回目以降のアクセスでしょ?

その通りです。説明をサボってました。

1回目のアクセスはOPcacheに乗っていないので、PHPスクリプトコンパイルをしてOPcahceの最適化処理が走って共有メモリ上に配列を構築する必要があるので、かなり遅いです。本気で使うならpreloadingopcache_compile_file()の利用を検討した方がいいでしょう。

逆に2回目アクセスではキャッシュから取り出したopcode列の時点で不変配列を参照しているので、そりゃ速いよねという理屈です。

感想など

今年のPHPerKaigiはオンラインでしたが、非常に面白かったです。講演は事前収録でしたが、自分の収録を見ながらDiscordで出た質問に答えるという体験のは新鮮でした。

また、飽きさせないような仕掛けが多いのも良かったと思います。講演中にニコニコでコメントが流れてくるのも良かったですし、休み時間にDiscordで雑談がはじまったり、Zoomでアンカンファレンスが開催されていたりで、オフラインとは違った面白さを感じました。

最後になりますが、スタッフの皆様、今年もおつかれさまでした。これほどの規模になると運営は本当に大変だと思いますが、来年も期待しておりますのでよろしくお願いいたします。


  1. 縦だけでなく横にも長いことが多いです