35

変数xは可能な値を持つ int です: -1, 0, 1, 2, 3. どちらの式が高速になりますか (CPU ティックで):

1. (x < 0)
2. (x == -1)

言語: C/C++ ですが、他のすべての言語も同じだと思います。

PS私は個人的にその答えはだと思います(x < 0)

教祖のためにもっと広く: もしxから-1まで2^30?

4

12 に答える 12

80

それは、コンパイルする ISA と、コンパイラのオプティマイザの品質に完全に依存します。時期尚早に最適化しないでください。最初にプロファイリングしてボトルネックを見つけてください

とはいえ、x86 では、ほとんどの場合、どちらも同等に高速であることがわかります。どちらの場合も、比較 ( ) 命令cmpと条件付きジャンプ ( jCC) 命令があります。ただし、 の(x < 0)場合、コンパイラが命令を省略してコードを1 サイクル全体cmpで高速化できる場合があります。

具体的には、値xがレジスタに格納されていて、最近、EFLAGS レジスタに符号フラグ SF を設定する算術演算 ( add、またはなどsub、さらに多くの可能性があります) の結果であった場合、cmp命令は必要ありません。 、コンパイラはjs命令だけを発行できます。jCC入力が -1 のときにジャンプする単純な命令はありません。

于 2009-05-26T19:37:28.647 に答える
11

試してみてください!それぞれを100万回、またはそれ以上、10億回実行し、時間を計ります。結果に統計的有意性はないと思いますが、プラットフォームとコンパイラで結果が得られる可能性があります。

これは、時期尚早の最適化はおそらく時間の無駄であり、「少なくともプログラミングにおけるすべての悪の根源」である可能性があることを自分自身に納得させるための素晴らしい実験です。

于 2009-05-26T19:34:19.040 に答える
8

x < 0 の方が高速です。他に何もないとしても、定数 -1 をオペランドとしてフェッチすることを防ぎます。ほとんどのアーキテクチャには、ゼロと比較するための特別な命令があるため、それも役立ちます。

于 2009-05-27T04:10:27.093 に答える
8

どちらの操作も単一の CPU ステップで実行できるため、パフォーマンスに関しては同じである必要があります。

于 2009-05-26T19:27:38.697 に答える
3

とにかく、重要な考慮事項は、実際にプログラム フローを正確に指示するのはどれか、そしてたまたま同じ結果を生成するのはどれかということです。

x が実際に列挙型のインデックスまたは値である場合、常に -1 が必要ですか、それとも負の値は機能しますか? 現在、マイナスは -1 だけですが、これは変更される可能性があります。

于 2009-05-26T19:32:39.873 に答える
3

文脈から外れたこの質問に答えることさえできません。些細なマイクロベンチマークを試してみると、オプティマイザーがコードをエーテルに送り込む可能性は十分にあります。

// 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.
于 2009-05-26T19:34:41.897 に答える
1

アーキテクチャにもよりますが、 x == -1 の方がエラーが発生しやすいです。x < 0 が道のりです。

于 2009-05-27T09:01:58.773 に答える
1

他の方もおっしゃっているように、おそらく違いはありません。比較は、CPU の基本的な操作であるため、チップ設計者は可能な限り高速にしたいと考えています。

しかし、他にも考えられることがあります。各値の頻度を分析し、その順序で比較します。これにより、かなりの数のサイクルを節約できます。もちろん、これを確認するには、コードを asm にコンパイルする必要があります。

于 2009-05-28T16:41:08.223 に答える
1

同じ、両方の操作は通常 1 クロックで行われます。

于 2009-05-26T19:27:01.863 に答える
1

ニコライ、あなたは次のように書いています:

これは、実際には高負荷プログラムのボトルネック オペレーターです。この 1 ~ 2 文字列でのパフォーマンスは、読みやすさよりもはるかに価値があります...

完璧なアルゴリズムを備えた完璧な設計であっても、通常、すべてのボトルネックはこれほど小さいものです (そのようなものはありません)。私は高負荷の DNA 処理を行っており、自分の分野とアルゴリズムをよく知っています

もしそうなら、なぜ次にしないのか:

  1. タイマーを取得し、0 に設定します。
  2. 高負荷プログラムを(x < 0)でコンパイルします。
  3. プログラムとタイマーを開始します。
  4. プログラムの最後にタイマーを見て、result1 を覚えておいてください。
  5. 1 と同じ。
  6. 高負荷プログラムを(x == -1)でコンパイルします。
  7. 3と同じ;
  8. プログラムの最後にタイマーを見て、result2 を覚えておいてください。
  9. 結果 1 と結果 2 を比較します。

あなたは答えを得るでしょう。

于 2009-08-25T06:38:07.230 に答える
1

私はあなたがこれがリアルタイムテイカーであると確信していると確信しています.

機械に聞いたほうが、私たちの誰よりも信頼できる答えが返ってくると思います。

あなたが話しているようなコードであっても、時間がどこに向かっているのかを知っていたという私の仮定は、まったく正しくないことがわかりました。たとえば、これが内部ループにある場合、コンパイラによって挿入された目に見えないものであっても、何らかの関数呼び出しがある場合、その呼び出しのコストがはるかに大きくなります。

于 2009-05-28T19:42:08.263 に答える