PHP7から、PHP関数の引数を処理する内部関数の高速版が作られました。従来の引数パーサが廃止されるわけではなく、今後も両方が併用されます。
これはC言語のレイヤの話題ですから、PHPプログラマに直接関係する内容ではありません。また、PHPエクステンション開発者であっても新APIを使う機会はないでしょう。従来通りの書き方のままで問題ないはずです(理由は後述)。
実装
新旧のインターフェースを実際のコードで見てみましょう。下記はPHP7のis_a
関数の実装部分の抜粋です。
#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zS|b", &obj, &class_name, &allow_string) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_ZVAL(obj)
Z_PARAM_STR(class_name)
Z_PARAM_OPTIONAL
Z_PARAM_BOOL(allow_string)
ZEND_PARSE_PARAMETERS_END();
#endif
PHP5で引数の処理を行う場合、このコードの前半部のようにzend_parse_parameters()
関数が用いられていました。PHP7からはZEND_PARSE_PARAMETERS_**
およびZ_PARAM_**
というマクロ関数が導入されています。これらはzend_parse_parameters()
関数と同等の機能をマクロで実現しています。それぞれで必要な機能だけがベタ書きで展開されるので、速度的には有利になります。一方、バイナリサイズの観点では不利になります。
この新APIは速度が本当に重要な箇所でのみ使うべきだとされています。バイナリサイズを無意味に大きくしてキャッシュ効率を下げてしまうことを懸念しているのかもしれません。実際、PHP7のソースコード中で使われている場所は103箇所でした。PHP本体および標準エクステンションに含まれるPHP関数・メソッドの数は5000ほどですから、ごく一部にしか使われていないことがわかります。自作エクステンションで実装する関数は標準関数よりもずっと呼び出し頻度が低いはずですから、一般人が新APIを使う必要性はほとんど無いように思います。
速度改善
WordPressでベンチマークテストをしたところ、この新APIの導入により処理時間を2.5%ほど高速化できたそうです。