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 |