2017-07-11 12 views
2

私はこの質問が非常に些細かもしれませんし、違いが小さいので質問する価値がないことは知っていますが、とにかく不思議です。数値がソートされていない2桁の間隔に含まれているかどうかを確認する最も効率的な方法は?

3つのfloat、 'a'、 'b'、 'number'を考えてみましょう。 'number'が境界 'a'と 'b'の間隔内に含まれているかどうかを知りたい。

'a'と 'b'は間隔の制限ですが、 'a'は 'b'より小さくてもよく、逆も同様です。

どの機能が最も速い結果をもたらすか?

1)

bool isNumberInInterval(float a, float b, float number) 
{ 
    if (a < b) 
    { 
     return ((a <= number) && (number <= b)); 
    } 
    else 
    { 
     return ((b <= number) && (number <= a)); 
    } 
} 

2)

bool isNumberInInterval(float a, float b, float number) 
{ 
    return (((b <= number) && (number <= a)) || ((a <= number) && (number <= b))); 
} 
+1

_Which機能は、最速の結果を与えるだろう_あなたはそれぞれのケースをプロファイリングしてみてくださいましたか? –

+0

このコードはブランチでいっぱいですので、あなたのコンパイラが本当にうまくいかない限り、おそらく吸うでしょう。良いパフォーマンスが必要な場合は、関数を呼び出すたびにすべての数値がランダムであるかどうかを知る必要があります(信頼できないのでブランチを完全に作成する)か、そうでない場合は分岐予測子を最適化しようとします。たとえば、 'a'と' b'がいくつかの呼び出しで同じままである場合、最初の方法はおそらく良いでしょう。 – meneldal

+0

スマーフ速く。コンパイラが最適化を完了した後であれば、その差はごくわずかです。最初の方が読みやすくなります – user4581301

答えて

2

どちらが速いのかは言うまでもありません。それは多くのもの(数値の分布、分岐予測、コンパイラ)に依存します。それをベンチマークする必要があります。私のPC上では、GCC 6.3で、一様な分散[0; 1]の数で、速度は同じです。

この亜種は、(それが私のPC上であなたの変種よりも25%高速である)より速く、現在のPC上で次のようになります。

bool isNumberInInterval(float a, float b, float number) 
{ 
    return (a-number)*(b-number)<=0; 
} 
0

これはおそらく、マシンおよびコンパイラに多くを依存しています。しかし、最初の方が速いと主張することができます。

最初のバージョンは、最大で3回の比較と1回の論理演算を実行します。しかし、最初のオペランドがfalseのときに&&を短絡することができれば、2回の比較と0回の論理演算を実行できます。

第2のバージョンの最悪の場合は、4回の比較と3回の論理演算です。しかし、少なくとも2回の比較と1回の論理演算を実行する必要があります。&&||の両方を短絡することはできません。

関連する問題