php in_arrayの低パフォーマンス
2876 ワード
PS:オリジナル文章、転載する必要がある場合は、出典を明記してください.ありがとうございます.
本住所:http://flyer0126.iteye.com/blog/2270090
PHP 7は最近発売されましたが、主に性能の向上です.in_の場合array()はずっと非難されていますが、性能がどれだけ悪いかは、まず簡単にテストして、データを見てみましょう.
テスト手順は次のとおりです.
テスト結果
in_array方式1.文字型文字列//3 k消費時間:1.0687351226807//3 w消費時間:10.569030044632.int型文字列//3 k消費時間:1.0500609874725//3 w消費時間:10.290988922119
isset方式1.文字型文字列//3 k消費時間:0.000299682617188//3 w消費時間:0.00089990764617991992.int型文字列//3 k消費時間:0.000108947753906//3 w消費時間:0.0008568763329102
上記のテストデータと組み合わせて、2つの方法の性能の差は明らかです.
ltraceを使用して、プロセスがライブラリ関数を呼び出す状況を追跡します.
ライブラリ関数を参照_strtol_internalの呼び出しは非常に頻繁で、このライブラリ関数_strtol_internalはもとはstrtolの別名で、簡単に言えば文字列を変換して整形し、PHPエンジンが文字列型の数字であることを検出したと推測できるので、彼らを変換して成長型全体を比較することを期待しています.この変換の過程で時間がかかりすぎて、私たちは再び実行します.
このような呼び出しを簡単につかむことができます.これで、問題が見つかりました.in_arrayという松の比較は,2文字型の数字列を先に長整数型に変換して比較するが,性能がこの上に消費されることを知らない.
問題点を知ったら、私たちの解決策はたくさんあります.最も簡単なのはinです.arrayは3番目のパラメータをtrueに追加し、厳密な比較になり、同時にタイプを比較することで、PHPの自業自得な変換タイプを回避し、走るのはやはり速くなりました.コードは以下の通りです.
まとめると、大きな配列のクエリーは、in_array関数は悪い選択です.できるだけisset関数で置き換えるべきです.in_array関数の複雑さはO(n)であり,isset関数の複雑さはO(1)である.
本住所:http://flyer0126.iteye.com/blog/2270090
PHP 7は最近発売されましたが、主に性能の向上です.in_の場合array()はずっと非難されていますが、性能がどれだけ悪いかは、まず簡単にテストして、データを見てみましょう.
テスト手順は次のとおりです.
<?php
/**
* ( )
* @return float
*/
function microtime_float(){
list($usec, $sec) = explode(' ', microtime());
return ((float)$usec + (float)$sec);
}
/**
*
*/
$int_arr = $str_arr = [];
for($i=0; $i<200000; $i++){
$int_arr[] = $i;
$str_arr[] = "{$i}";
}
$time_start = microtime_float();
//
for($j=0; $j<3000; $j++){
if(in_array(18000, $int_arr)){
continue;
}
// if(isset($int_arr[$key])){
// continue;
// }
}
$time_end = microtime_float();
echo ' :'.($time_end - $time_start);
テスト結果
in_array方式1.文字型文字列//3 k消費時間:1.0687351226807//3 w消費時間:10.569030044632.int型文字列//3 k消費時間:1.0500609874725//3 w消費時間:10.290988922119
isset方式1.文字型文字列//3 k消費時間:0.000299682617188//3 w消費時間:0.00089990764617991992.int型文字列//3 k消費時間:0.000108947753906//3 w消費時間:0.0008568763329102
上記のテストデータと組み合わせて、2つの方法の性能の差は明らかです.
ltraceを使用して、プロセスがライブラリ関数を呼び出す状況を追跡します.
$ ltrace -c /usr/local/php/bin/php test.php
ライブラリ関数を参照_strtol_internalの呼び出しは非常に頻繁で、このライブラリ関数_strtol_internalはもとはstrtolの別名で、簡単に言えば文字列を変換して整形し、PHPエンジンが文字列型の数字であることを検出したと推測できるので、彼らを変換して成長型全体を比較することを期待しています.この変換の過程で時間がかかりすぎて、私たちは再び実行します.
$ ltrace -e "__strtol_internal" /usr/local/php/bin/php test.php
このような呼び出しを簡単につかむことができます.これで、問題が見つかりました.in_arrayという松の比較は,2文字型の数字列を先に長整数型に変換して比較するが,性能がこの上に消費されることを知らない.
問題点を知ったら、私たちの解決策はたくさんあります.最も簡単なのはinです.arrayは3番目のパラメータをtrueに追加し、厳密な比較になり、同時にタイプを比較することで、PHPの自業自得な変換タイプを回避し、走るのはやはり速くなりました.コードは以下の通りです.
in_array(search,array,type)
, :
in_array(18000, $int_arr, true);
in_array('18000', $str_arr, true);
3k :0.88052606582642、0.8897430896759
まとめると、大きな配列のクエリーは、in_array関数は悪い選択です.できるだけisset関数で置き換えるべきです.in_array関数の複雑さはO(n)であり,isset関数の複雑さはO(1)である.