「より良い」解決策を提供することは常に困難です (コード行、読みやすさ、実行速度、マシンコード命令のバイト数など、どの点でより良いのでしょうか?)。この場合、それに集中できます。
提案するその変数を導入し、それを使用して条件を単純なより小さい条件に減らし、答えがわかったら使用できます。より小さい条件は、ほとんどのアーキテクチャで 2 つのマシン コード命令に自明に変換されます (たとえば、Intel IA-32ではCMP
(compare) の後にJL
(より小さい場合はジャンプ) または(小さくない場合はジャンプ) が続きます)。少し運が良ければ、コンパイラーは最初の 2 つのステートメントで常にtrue になるJNL
ことに気付き (または自分で行うこともできますが、どこでも同じパターンを持つことで得られる明快さを好みます)、それを最適化します。trues < 2
if()
int trues = 0;
if (trues < 2 && condition1) trues++;
if (trues < 2 && condition2) trues++;
if (trues < 2 && condition3) trues++;
// ...
if (trues >= 2)
{
// do something
}
これは、答えが分かれconditionN
ば、ほとんどの言語のブール短絡動作のために、複雑な可能性のある評価を単純なより小さい比較に減らします。
言語でブール条件を整数にキャストできる場合は、それを利用してソースコードの行数を減らすことができます。ただし、引き続き各条件を評価します。
if( (int)(condition1)
+ (int)(condition2)
+ (int)(condition3)
>= 2)
{
// do something
}
これは、ブール値の FALSE 値を整数にキャストすると 0 になり、TRUE をキャストすると 1 になるという前提に基づいて機能します。同じ効果のために条件演算子を使用することもできますが、追加の分岐が発生する可能性があることに注意してください。
if( ((condition1) ? 1 : 0)
+ ((condition2) ? 1 : 0)
+ ((condition3) ? 1 : 0)
>= 2)
{
// do something
}
コンパイラのオプティマイザーの能力によっては、2 つの条件が true と評価されると、条件全体が常に true と評価され、それに基づいて最適化されると判断できる場合があります。
- コードを実際にプロファイリングして、これが原因であると判断した場合を除き、最適化が時期尚早である可能性が高いことに注意してください。見ているコードの特定の部分が実際のパフォーマンスのボトルネックであるという決定的な証拠を示すことができない限り、コードは常に最初に人間のプログラマーが読み取り可能であり、次にコンピューターが高速に実行できるように努めてください。そのプロファイラーがどのように機能するかを学び、有効に活用してください。ほとんどの場合、プログラマーの時間は CPU 時間よりもはるかにコストがかかり、巧妙な手法はメンテナンス プログラマーが解析するのに時間がかかることに注意してください。
- また、コンパイラは非常に賢いソフトウェアです。書かれたコードの意図を実際に検出し、それらの操作を高速化するための特定の構造を使用できる場合もありますが、それは、何をしようとしているのかを判断できることに依存しています。これの完璧な例は、中間変数を使用して 2 つの変数を交換することです。これは、IA-32
XCHG
では中間変数を削除することで実行できますが、コンパイラーは、実際にそれを行っていることを判断できなければならず、何かを与える可能性のある巧妙なものではありません。場合によっては別結果。
- 明示的に書かれていない使い捨てソフトウェアの大部分は、そのライフタイムの大部分を保守モードで過ごすため (そして、書かれた使い捨てソフトウェアの多くは有効であり、意図した賞味期限をはるかに過ぎています)、保守性を最適化することは理にかなっています。それが他の点で容認できないほどの代償を伴う場合を除きます。もちろん、これらの条件をタイトなループ内で 1 兆回も評価している場合、ターゲットを絞った最適化は非常に理にかなっている可能性があります。しかし、プロファイラーは、コードのどの部分をパフォーマンスの観点からより綿密に精査する必要があるかを正確に教えてくれるので、コードが不必要に複雑になるのを避けることができます。
そして、上記の注意点によると、私は最近コードに取り組んでおり、一見したところ、詳細の最適化が時期尚早であるとほぼ確実に考えられるような変更を加えています。高パフォーマンスが必要で、プロファイラーを使用してコードのどの部分がボトルネックであるかを判断する場合、最適化は時期尚早ではありません。(ただし、正確な状況によっては、依然として不適切な場合があります。)