PHP 文字を連結するときの処理速度とメモリ使用量の比較
文字を適当な文字をつけて連結していきたいけど、配列にしてからimplode()するか、「.=」で文字をくっつけていくかで悩む。
作成日:2018-07-24, 更新日:2023-03-01
経緯
・受け取った文字列をURLにくっつけるgetパラメータにしたい。
内容としては・・・
・最初は「?」
・以降は「&」を区切り文字にしてくっつけたい。
色々と試していたら処理速度やメモリが気になった。
以下は、流れ(※実際はもっと複雑だけどシンプルにしてみた)
仮案1
最初は・・・下記のような感じにしていた。
$str .= (($str!='')? '&': '') . 'hoge=' . $hoge; $str .= (($str!='')? '&': '') . 'foo=' . $foo; $url = '〇〇〇?' . $str
仮案2
なんとなく見づらくてイヤだったので、いったん配列にしてからimplode()で吐き出そうと思った。
$seed[] = 'hoge=' . $hoge;
$seed[] = 'foo=' . $foo;
$url = '〇〇〇?' . implode('&', $seed)
仮案3
「配列にすると重くなるんじゃないの?」・・・と思い一つ目のやり方を見やすくしようとした。
function addStr($str, $add) {
$result = $str
. (($str!='')? '&': '')
. $add;
return $result;
}
$str .= addStr($str, 'hoge=' . $hoge);
$str .= addStr($str, 'foo=' . $foo);
$url = '〇〇〇?' . $str
計測
それぞれの方法で処理速度と使用したメモリを比較してみた
function addWithDelimiter($seedStr='', $addStr='', $delimiter='') {
$result = $seedStr;
if ( $addStr == '' ) {
return $result;
}
if ( $result != '' ) {
$result .= $delimiter;
}
$result .= $addStr;
return $result;
}
function processTime($fstAt, $finAt){
list($finS, $finM) = explode(' ', $finAt);
list($fstS, $fstM) = explode(' ', $fstAt);
return ((float)$finS-(float)$fstS) + ((float)$finM-(float)$fstM);
}
function diffMemorySize($fstMemSize){
return (memory_get_usage() - $fstMemSize);
}
$max = 10000;
// if{}で文字連結
$fstMemSize = memory_get_usage();
$fstAt = microtime();
$str = '';
for ( $i=0; $i<$max; $i++ ) {
$str .= (($str!='')? ',': '') . $i;
}
$finAt = microtime();
echo processTime($fstAt, $finAt) . ' / ' . diffMemorySize($fstMemSize);
unset($str);
// 配列格納後、implode()
$fstMemSize = memory_get_usage();
$fstAt = microtime();
$ary = array();
for ( $i=0; $i<$max; $i++ ) {
$ary[] = $i;
}
$str = implode(',', $ary);
$finAt = microtime();
echo processTime($fstAt, $finAt) . ' / ' . diffMemorySize($fstMemSize);
unset($str,$ary);
// 「if{}で文字連結」を別関数にする
$fstMemSize = memory_get_usage();
$fstAt = microtime();
$str = '';
for ( $i=0; $i<$max; $i++ ) {
$str = addWithDelimiter($str, $i, ',');
}
$finAt = microtime();
echo processTime($fstAt, $finAt) . ' / ' . diffMemorySize($fstMemSize);
unset($str);
結果
処理速度に厳しい案件なら気にしたほうがいいけど、個人的に見づらいけど「if{}」で連結させるのが良さげと結論。
| 処理の内容 | 処理時間 | 使用メモリ |
|---|---|---|
| if{}で文字連結 | 0.010~0.016 秒 | 49,488 byte |
| 配列格納後、implode() | 0.008~0.013 秒 | 914,648 byte |
| 「if{}で文字連結」を別関数にする | 0.040~0.050 秒 | 49,496 byte |