配列を反復処理し、値で曜日に並べ替えています。
それを行うために、私は多くのif
ステートメントを使用しています。if
一連のelse if
ステートメントと比較して、多くのを使用する場合、処理速度に違いはありますか?
配列を反復処理し、値で曜日に並べ替えています。
それを行うために、私は多くのif
ステートメントを使用しています。if
一連のelse if
ステートメントと比較して、多くのを使用する場合、処理速度に違いはありますか?
はい、次のコードを検討する場合は、elseを使用してください。
if(predicateA){
//do Stuff
}
if(predicateB){
// do more stuff
}
の
if(predicateA){
//
}
else if(predicateB){
//
}
2番目のケースでは、predicateAがtrueの場合、predicateB(およびそれ以降の述語)を評価する必要はありません(したがって、コード全体がより高速に実行されます)。一方、最初の例では、predicateAがtrueの場合、predicateBは常に評価されます。また、predicateAとpredicateBが相互に排他的でない場合は、予期しない驚きが生じる可能性があります。
このようなマイクロ最適化がコードに測定可能な違いをもたらすとは思えません。
並べ替えアルゴリズムがパフォーマンスの問題の原因である可能性が高くなります。どのソートアルゴリズムを選択するかが重要になります。「ifs」と「elseif」の数は多くありません。
アップデート:
「elseif」がより良い選択であるという他の人の指摘は、その早期終了と排他的な論理特性のために、この場合は「if」よりも優先されるべきであることを示唆しています。
ただし、データセットが非常に小さい場合を除いて、アルゴリズムの選択に関するポイントは依然として有効です。
O(log n)がO(n ^ 2)よりも優れていることは明らかですが、データセットのサイズも重要です。要素が少ない場合は、違いに気付かない可能性があります。その場合、一目で最もクリーンで、最も読みやすく、最も理解しやすい方法で非効率的なメソッドをコーディングするのが最善の策かもしれません。
正直なところ、パフォーマンスの面でどちらの方法で行うかは問題ではないと思います。違いが見られるとは思えません。パフォーマンスの向上ではなく、単に構文的に優れたswitchステートメントを使用することをお勧めします。
switch ($day)
{
case "Monday":
// do something with Monday
break;
case "Tuesday":
// do something with Tuesday
break;
case "Wednesday":
// do something with Wednesday
break;
}
連続するif()とif()の間に真の違いがある場合は、ベンチマークを作成しました。その後、いくつかのelseif()
私は大きな文字列を入れて、2つのメソッドで毎回約20 strpos()(x100 000)を実行しましたが、次の結果が示されました。
Try 1 : 0.5094 (including elseif)
Try 2 : 0.6700 (including only if)
間違いありません。途中でリターンがあったとしても、連続したelseif()の方が速いことはすでに知っていました。答えにいくつかの統計を入れるのはまだ良いことです。
else if
trueに解決される条件に到達するまで比較し、残りのをスキップするという意味で、より高速になりますif
。
また、頻度の降順で比較を並べ替えることを検討してください。
そして、switch
比較しているオブジェクトのデータ型に応じてステートメントを使用します。
ただし、この時点で、duffymoが示唆しているように、マイクロ最適化を行うことになります。最初にジョブに適切な並べ替えアルゴリズムを選択しなかった場合、パフォーマンスの向上はそれほど重要ではありません。
値が整数の場合、テーブルルックアップを使用して最適化を実現できます。たとえば、なんらかの方法で7日間にマッピングされる256個の値がある場合、256個のセルで配列を設定し、各セルに必要な曜日を含めることができます。次に、代わりに:
if ( value == 0 ) {
dayofweek = 1;
} else if ( value == 1 ) {
dayofweek = 2;
} else if ( value == 2 ) {
dayofweek = 3;
} else if ...
..あなたが持つことができます..
dayofweek = lookuparray[value];
もちろん、この手法を使用する場合は、最初に値の範囲を確認する必要があります。
代わりに、switch()ステートメントを選択するために別の投票を行います。
if
この質問は、ブロックが戻ってメソッドを終了するときに特に興味深いものです。また、Javaのコンパレータが機能する方法にも直接適用されます。
したがって、各メソッド(以下)を250.000.000回実行したところ、結果は次のようになります。
two values if/else - 6.43 millis
three values if/else/if - 8.66 millis
three values if/if - 9.01 millis
最悪の場合は最良の場合の1.4倍の時間がかかりますが、これはこれらの各メソッドを2億5000万回繰り返した合計であることに注意してください。人間が遅延を認識するのに100ミリ秒かかり、最悪/より良い差が2.58ミリであると仮定すると、異なる方法の違いを認識するには、ほぼ1兆(1000 * 1億)回の反復が必要になることを意味します。
要約すると、これif-else
は、最速のオプションが読みやすく、エラーが発生しにくいオプションでもある場合の1つです。
// methods used to measure difference between if and if/else
/** equality is not important **/
private static int comparatorOfIfElse(int a, int b) {
if(a < b) return -1;
else return 1;
}
/** equality is taken into account using if/else **/
private static int comparatorOfIfElseIf(int a, int b) {
if(a < b) return -1;
else if(a > b) return 1;
return 0;
}
/** equality is taken into account using only if **/
private static int comparatorOfIf(int a, int b) {
if(a < b) return -1;
if(a > b) return 1;
return 0;
}
多くのifステートメントまたは1つのif-elseif-elseif...を使用するという決定は、プログラムフローに大規模に関係するため、パフォーマンスに依存するべきではありません。
機能を失うことなく、多くのifステートメントから大きなif-elseifに切り替えることができるとは思えません。
その設計上の問題であり、パフォーマンスに関する問題ではありません。
一般に、一連のifでは、すべての条件が次々にチェックされるため、「elseif」スタイルの方が高速です。「elseif」チェーンでは、1つの条件が一致すると、残りはバイパスされます。
最も速いのはテーブルディスパッチです。これは、十分なケースがある場合にswitchステートメントが最適化されるものです(スイッチにケースがほとんどない場合は、結果のマシンコードで一連のif-elseチェックに変換されます) )。