2019年11月25日

PHP の join は本当に implode より速いのか

新人の頃に PHP に関して「join と implode はどっちがいいですか」と質問したら「join のほうが速い」と即答された。

その話の続きは一旦置いといて、いま検索してみても高速化やチューニングの記事で join を推すものが見つかった。しかもベンチマークの結果付きで。本当に?

仕様を確認する

PHP のマニュアルでは join についてシンプルにこう書かれている。

join — implode() のエイリアス

PHP: join - Manual

ソースを見ても確かにエイリアス。

# ext/standard/basic_functions.c
PHP_FALIAS(join, implode, arginfo_implode)

ベンチマーク

あとはベンチマークを取ってみる。 microtime を使った極めて単純なもの。PHP 7.2 で実行。

<?php
$loop = 100000;
$trial = 500;

$results = array();
$glue = ",";
$pieces = array();
for( $i=0; $i < 10; $i++ ) {
  $pieces[] = "ABCDEFG";
}

for( $j=0; $j < $trial; $j++ ) {
  $start = microtime(true);
  for( $k=0; $k < $loop; $k++) {
    join($glue, $pieces);
  }
  $results["join"] = microtime(true) - $start;

  $start = microtime(true);
  for( $l=0; $l < $loop; $l++ ) {
    implode($glue, $pieces);
  }
  $results["implode"] = microtime(true) - $start;

  echo $results["implode"] . "\t" . $results["join"] . "\n";
}

結果、 join を100%とすると implode が100.11%速かった。5000万回あたり0.005秒節約できます!

試行ごとのばらつきがひどかったので10万回のループを500回実行し、スクリプトを修正して関数呼び出しの順番を入れ替えてまた500回実行している。その上で implode の方が速かったのは1000回中516回とほぼ半々。少なくとも現行バージョンでは「エイリアス(なのに/だから)パフォーマンスが高い」ということはないわけだ。

どちらを使うべきか

PHP マニュアルではエイリアスについてこう説明している。

いくつかの場合、これら複数の名前のどちらかが好ましいとはされていません。例えば、is_int()is_integer() は等しく好ましいとされています。

しかし…古い名前が下位互換性の維持のためだけに残されている場合があり…移植性の低いスクリプトとなるため推奨されません。

PHP: 関数エイリアスのリスト - Manual

その後にエイリアスのリストが続くが、例示の is_int 以外はどちらに該当するか書かれていないので結局どうすればいいんだという気分になる。

こうなるとどちらを選ぶかは宗教戦争。いままでに見聞きしたのは:

  • 他言語での分割連結は split / join が一般的だから join だ
  • じゃあむしろ implode を使う、PHPは他とは違うんだ!
  • implode と explode はイメージが沸かなくて覚えづらいから split / join
    ちなみにこのとき知った「join する方が implode」という覚え方はいまだにお世話になっている
  • エイリアスというものは使うべきではないから implode

PHP のソースコードをざっと調べたら implode のほうが4倍近く使われていた。ただしこれはもうメンテナンスされてなさそうなテストやサンプルスクリプトも含めてるし、コピペっぽい繰り返しも散見されたのでまあ参考までに。

split が廃止となった現在では「explode / implode の方が統一感があるから implode」というのが一番つよい気がする。

ちなみに

冒頭の話のオチは「join のほうが3文字短いから」。

高速化するなら join ってのはジョークから生まれた都市伝説なのかもしれない。

posted by かぷらす at 19:02| Comment(0) | 調査 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
コチラをクリックしてください