ラボ > PHP:配列関連、文字関連

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

関連項目