続き

と悪態だけで終わってしまうと某所と同じなので,もう少し詳しく.
上記テストに使った関数.

function Test1($string) {
    $s = ereg_replace("[\x09\x0A\x0D]",'',$string);
}

function Test2($string) {
    $s = preg_replace('#[\x09\x0A\x0D]#','',$string);
}

function Test3($string) {
    $s = str_replace (
      "\x09",'',
        str_replace(
          (
            false === $iCR = strpos($string,"\x0D",0)
            ? "\x0A"
            : ($string{$iCR + 1} === "\x0A" ? "\x0D\x0A" : "\x0D")
          ),
          '',
          $string
        )
      );
}

Test3を分かりやすく書き直すと(Test4)・・・

function Test4($string) {
    // キャリッジリターン("\x0D")がない:UNIX
    if (false === $iCR = strpos($string,"\x0D",0))
      {
        $sLineEnd = "\x0A";
      }
    // キャリッジリターンにラインエンド(\x0A)が続く:Windows
    elseif ($string{$iCR + 1} === "\x0A")
      {
        $sLineEnd = "\x0D\x0A";
      }
    // キャリッジリターンのみ:Mac
    else
      {
        $sLineEnd = "\x0D";
      }
    // 改行コードを除去
    $line = str_replace($sLineEnd,'',$string);
    // タブ文字を除去
    $s = str_replace ("\x09",'',$string);
}

やってることは同じだけど,

  • 改行コードをいったん変数に代入した分
  • 改行コードを除去した文字列を変数に代入した分

処理が遅くなるはず.(Zendの誰かが,「余計な変数使うと遅くなるよ」と書いてた)
Test3も,Test1,Test2と同様に改行コードを無視して\x0Dも\x0Aも削除するなら(Test5)・・・

function Test5($string) {
    $s = str_replace ("\x09",'',
      str_replace("\x0A",'',
        str_replace("\x0D",'',$string)
        )
      );
}

PHPでは変数作成よりも配列作成に時間がかかるが,関数コールはもっと時間がかかるので,関数コールを減らしてみる(Test6)

function Test6($string) {
    $s = str_replace (array("\x09","\x0A","\x0D"),'',$string);
}

ついでに,strtr() 版(Test7)

function Test7($string) {
    $s = strtr($string,array("?x09"=>'',"?x0A"=>'',"?x0D"=>''));
}

str_replace() と ereg_replace() のパラメータを " でなく ' で括っているのは,関数側で16進表記を展開できないから*1

それぞれに与えた文字列は,いつも使ってるランダム文字列生成スクリプト(変数/関数名として有効な文字=[a-zA-Z_\x7F-\xFF]だけで構成).(4.2.0未満なら mt_srand() を追加)(下記のスクリプトはあまりよろしくないので今は別の形式を使ってる.今使ってるモノよりもこちらの方が処理内容が分かりやすいので,あくまでも参考として)

function getRandamChar($num = false) {
    if ($num) {
        return
          (
            (26 > ($char = mt_rand(1,142) % 142))
            ? chr($char + 65)
            :
              (
                ($char < 52)
                ? chr($char + 71)
                :
                  (
                    ($char < 130)
                    ? chr($char + 125)
                    :
                    (
                      ($char === 131)
                      ? '_'
                      : ($char - 132)
                    )
                  )
              )
          );
    } else {
        return
          (
            (26 > ($char = mt_rand(1,132) % 132))
            ? chr($char + 65)
            :
              (
                ($char < 52)
                ? chr($char + 71)
                :
                  (
                    ($char < 130)
                    ? chr($char + 125)
                    : '_'
                  )
              )
          );
    }//end if
}//end func

function makeText($byte = 1024,$lines = 1) {
    $string = '';
    $byte   = $byte / $lines;//1行あたりの文字数
    for ($i = 0;$i < $lines;$i++) {
        for ($j = 0;$j < $byte;$j++) {
            $string = $string . getRandamChar();
        }//end for[2]
        $string = $string . "\n";
    }//end for[1]
    // 普段はこのまま return
    return str_replace(getRandamChar(),"\t",$string);
}//end func

これまた,いつもつかってる速度比較関数*2で,上記3つのテスト用関数に 引数[ makeText(10240,10) ]を与えて実行(各テスト用関数に与えた引数はランダムでなく全て同じもの).
各関数を10回繰り返し(1回目〜10回目),マイクロ秒単位で処理時間を取得,さらにその10回平均を取得.以下,その結果.

function name 1回目 2回目 3回目 4回目 5回目 6回目 7回目 8回目 9回目 10回目 平均
test1 ereg 0.0653 0.0649 0.0809 0.0707 0.0932 0.0648 0.0720 0.0737 0.0644 0.0668 0.069874
test2 preg 0.0578 0.0571 0.0527 0.0569 0.0592 0.0557 0.0676 0.0701 0.0524 0.0578 0.058092
test3 str 0.0058 0.0059 0.0060 0.0058 0.0172 0.0061 0.0063 0.0064 0.0058 0.0058 0.006008
test4 str * 2 0.0066 0.0060 0.0059 0.0076 0.0060 0.0060 0.0059 0.0059 0.0118 0.0060 0.006245
test5 str * 3 0.0076 0.0081 0.0057 0.0059 0.0076 0.0073 0.0133 0.0060 0.0058 0.0058 0.006755
test6 str + array 0.0037 0.0041 0.0037 0.0036 0.0037 0.0038 0.0038 0.0037 0.0037 0.0037 0.003704
test7 strtr 0.0251 0.0271 0.0264 0.0307 0.0251 0.0244 0.0254 0.0324 0.0260 0.0273 0.026643
最速 test6 test6 test6 test6 test6 test6 test6 test6 test6 test6 test6: 10回

結果は戦前の予想どおり.ともあれ,正規表現の使用は計画的に・・・

*1:preg_replace() はパターン内の16進表記を展開する

*2:正確にはクラス=オブジェクト.詳細省略