続き
と悪態だけで終わってしまうと某所と同じなので,もう少し詳しく.
上記テストに使った関数.
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回 |
結果は戦前の予想どおり.ともあれ,正規表現の使用は計画的に・・・