変数x
は可能な値を持つ int です: -1, 0, 1, 2, 3
. どちらの式が高速になりますか (CPU ティックで):
1. (x < 0)
2. (x == -1)
言語: C/C++ ですが、他のすべての言語も同じだと思います。
PS私は個人的にその答えはだと思います(x < 0)
。
教祖のためにもっと広く: もしx
から-1
まで2^30
?
変数x
は可能な値を持つ int です: -1, 0, 1, 2, 3
. どちらの式が高速になりますか (CPU ティックで):
1. (x < 0)
2. (x == -1)
言語: C/C++ ですが、他のすべての言語も同じだと思います。
PS私は個人的にその答えはだと思います(x < 0)
。
教祖のためにもっと広く: もしx
から-1
まで2^30
?
それは、コンパイルする ISA と、コンパイラのオプティマイザの品質に完全に依存します。時期尚早に最適化しないでください。最初にプロファイリングしてボトルネックを見つけてください。
とはいえ、x86 では、ほとんどの場合、どちらも同等に高速であることがわかります。どちらの場合も、比較 ( ) 命令cmp
と条件付きジャンプ ( jCC
) 命令があります。ただし、 の(x < 0)
場合、コンパイラが命令を省略してコードを1 サイクル全体cmp
で高速化できる場合があります。
具体的には、値x
がレジスタに格納されていて、最近、EFLAGS レジスタに符号フラグ SF を設定する算術演算 ( add
、またはなどsub
、さらに多くの可能性があります) の結果であった場合、cmp
命令は必要ありません。 、コンパイラはjs
命令だけを発行できます。jCC
入力が -1 のときにジャンプする単純な命令はありません。
試してみてください!それぞれを100万回、またはそれ以上、10億回実行し、時間を計ります。結果に統計的有意性はないと思いますが、プラットフォームとコンパイラで結果が得られる可能性があります。
これは、時期尚早の最適化はおそらく時間の無駄であり、「少なくともプログラミングにおけるすべての悪の根源」である可能性があることを自分自身に納得させるための素晴らしい実験です。
x < 0 の方が高速です。他に何もないとしても、定数 -1 をオペランドとしてフェッチすることを防ぎます。ほとんどのアーキテクチャには、ゼロと比較するための特別な命令があるため、それも役立ちます。
どちらの操作も単一の CPU ステップで実行できるため、パフォーマンスに関しては同じである必要があります。
とにかく、重要な考慮事項は、実際にプログラム フローを正確に指示するのはどれか、そしてたまたま同じ結果を生成するのはどれかということです。
x が実際に列挙型のインデックスまたは値である場合、常に -1 が必要ですか、それとも負の値は機能しますか? 現在、マイナスは -1 だけですが、これは変更される可能性があります。
文脈から外れたこの質問に答えることさえできません。些細なマイクロベンチマークを試してみると、オプティマイザーがコードをエーテルに送り込む可能性は十分にあります。
// Get time
int x = -1;
for (int i = 0; i < ONE_JILLION; i++) {
int dummy = (x < 0); // Poof! Dummy is ignored.
}
// Compute time difference - in the presence of good optimization
// expect this time difference to be close to useless.
アーキテクチャにもよりますが、 x == -1 の方がエラーが発生しやすいです。x < 0 が道のりです。
他の方もおっしゃっているように、おそらく違いはありません。比較は、CPU の基本的な操作であるため、チップ設計者は可能な限り高速にしたいと考えています。
しかし、他にも考えられることがあります。各値の頻度を分析し、その順序で比較します。これにより、かなりの数のサイクルを節約できます。もちろん、これを確認するには、コードを asm にコンパイルする必要があります。
同じ、両方の操作は通常 1 クロックで行われます。
ニコライ、あなたは次のように書いています:
これは、実際には高負荷プログラムのボトルネック オペレーターです。この 1 ~ 2 文字列でのパフォーマンスは、読みやすさよりもはるかに価値があります...
完璧なアルゴリズムを備えた完璧な設計であっても、通常、すべてのボトルネックはこれほど小さいものです (そのようなものはありません)。私は高負荷の DNA 処理を行っており、自分の分野とアルゴリズムをよく知っています
もしそうなら、なぜ次にしないのか:
あなたは答えを得るでしょう。
私はあなたがこれがリアルタイムテイカーであると確信していると確信しています.
機械に聞いたほうが、私たちの誰よりも信頼できる答えが返ってくると思います。
あなたが話しているようなコードであっても、時間がどこに向かっているのかを知っていたという私の仮定は、まったく正しくないことがわかりました。たとえば、これが内部ループにある場合、コンパイラによって挿入された目に見えないものであっても、何らかの関数呼び出しがある場合、その呼び出しのコストがはるかに大きくなります。