hnwの日記

PHP7で導入予定の新しいメモリマネージャをPHP5.6にバックポートした

現在、PHPの開発ブランチでは次期バージョンであるPHP7.0の開発が進められています。この新バージョンでは内部のリファクタリングと性能改善に重点が置かれるとみられており、言語仕様の観点ではメジャーバージョンアップの割に変化の小さいバージョンになりそうです。


ところで、このPHP7でメモリ管理まわりのコードが書き直されるのをご存じでしょうか。これはPHP7開発のキーマンの一人であるDmitry Stogovによるもので、アプリケーションによっては5%から10%の性能アップが期待できるようです。


しかし、PHP7は最速でも1年後のリリースと言われていますので、我々がこの恩恵を受ける日は随分先になってしまいます。そこで、この修正をPHP 5.6.2にバックポートしてみて、現行バージョンでも効果があるのかどうか実験してみました。

修正内容

PHP7で採用予定の新メモリマネージャは、最近の速いmalloc実装(jemallocやtcmallocなど)を参考にした実装をPHPに導入するものです*1


この修正は「New Memory Manager for PHP7 #777」で行われています。この差分をPHP 5.6.2に合わせて適宜修正したものが下記パッチです。


内容をあまり理解せずにパッチを作っているので、うまく動かないことがあるかもしれません。ただ、手元で少し試した限りではマトモに動いているようです。

ベンチマークテスト

オリジナルのPHP 5.6.2(old-mm)と、新メモリマネージャを組み込んだPHP 5.6.2(new-mm)とを用意し、ベンチマークテストZend/bench.phpMacOSX 10.9上で実行してみました。結果をまとめたものが次の表になります。

old-mm new-mm improvement
simple 0.115 0.113 1.7%
simplecall 0.126 0.110 12.7%
simpleucall 0.118 0.122 -3.4%
simpleudcall 0.124 0.125 -0.8%
mandel 0.295 0.301 -2.0%
mandel2 0.368 0.370 -0.5%
ackermann(7) 0.141 0.126 10.6%
ary(50000) 0.026 0.016 38.5%
ary2(50000) 0.023 0.009 60.9%
ary3(2000) 0.160 0.155 3.1%
fibo(30) 0.365 0.358 1.9%
hash1(50000) 0.029 0.023 20.7%
hash2(500) 0.036 0.033 8.3%
heapsort(20000) 0.093 0.084 9.7%
matrix(20) 0.095 0.082 13.7%
nestedloop(12) 0.194 0.198 -2.1%
sieve(30) 0.092 0.067 27.2%
strcat(200000) 0.013 0.011 15.4%
Total 2.413 2.303 4.6%


上記はbench.phpをそれぞれ6回実行し、総時間が最短のものと最長のものを取り除いた平均値です。


総計として4.6%の性能改善がみられました。個別の結果を見ても、大半のベンチマークテストについて新メモリマネージャの方が高速になっていると言えそうです。

まとめ

PHP7の新メモリマネージャは性能が良さそうであること、またPHP 5.6系にバックポートしても速度の観点で有利そうだということを紹介しました。


このパッチを商用サービスに適用するなどは論外だと思いますが、少しでも速度を稼ぎたいような状況があれば試してみてはいかがでしょうか。

*1:元々mallocの回数を抑制するような実装になっているのですが、何をどう改善したのかは理解していません…