1

例: 2 つの番号を交換する単純なプログラム。

 int a = 10;
 int b = 20;
 a = a+b;
 b = a-b;
 a = a-b;

次のコードで:

 a=a+b-(b=a);

つまり、これら 2 つのコードの違いは何ですか?

追加 : これら 2 つの追加が、Java と C++ の場合とは異なる整数の正当な制限を超えた場合はどうなりますか?

4

8 に答える 8

5

これらはどちらも私には良く見えません。読みやすさが鍵です。値を交換したい場合、最も「明白な」方法は、一時的な値を使用することです。

int a = 10;
int b = 20;

int tmp = a;
a = b;
b = tmp;

これが算術を含む「賢い」アプローチと同じくらい効率的であったかどうかは、私にはわかりませんし、気にすることもありません。パフォーマンスの違いが実際のアプリケーション内で重要であることを誰かが証明するまで、機能する最も単純なコードを目指します。ここだけでなく、すべてのコードに対して。どの程度のパフォーマンスが必要か (およびどの次元で) を決定し、テストし、必要に応じてより複雑で効率的なものに変更します。

(もちろん、swapプラットフォーム内で利用可能な操作がある場合は、代わりにそれを使用してください...さらに明確です。)

于 2012-10-13T08:24:39.643 に答える
5

a+b-(b=a)C++ では、シーケンス ポイントがなく、そこから変更bして読み取るため、コードは未定義の動作を引き起こします。

を使用しstd::swap(a,b)たほうがよいでしょう。速度が最適化されており、そこにあるものよりもはるかに読みやすくなっています。

于 2012-10-13T08:26:41.167 に答える
5

あなたの特定のコードはすでにコメントされているので、一般的な側面を追加します。命令レベルでは、アセンブリが機械語に変換されるステップ数を逃れることができないため、ライナーを 1 つ書くことは実際には問題ではありません。ほとんどのコンパイラは、すでにそれに応じて最適化しています。

つまり、1 つのライナーが実際に目標を達成するために別のメカニズムを使用していない限り、たとえば 2 つの変数を交換する場合、3 番目の変数を使用せず、型オーバーフローなどのすべてのハードルを回避し、ビット単位の演算子を使用できる場合を除きます。たとえば、1 つのメモリ ロケーションを保存して、そのロケーションにアクセスしたとします。

実際には、これはほとんど価値がなく、他の回答で既に述べたように読みやすさの問題です。専門的なプログラムは、人々によって維持される必要があるため、理解しやすいものでなければなりません。

優れたコードの 1 つの定義は、コードが実際に実行しているように見えることです。

あなた自身でさえ、短縮された複雑な操作に関して巧妙に記述されている場合、独自のコードを修正するのは難しいと感じるでしょう。読みやすさは常に優先されるべきであり、ほとんどの場合、実際に必要な効率は、短いワンライナーではなく、設計、アプローチ、またはより優れたデータ構造/アルゴリズムの改善から得られます。

Dijkstraの引用:有能なプログラマーは、自分の頭蓋骨のサイズが限られていることを十分に認識しています。したがって、彼は完全に謙虚に自分の仕事に取り組み、ペストのような巧妙なトリックを避けます.

于 2012-10-13T08:28:59.867 に答える
2

いくつかのポイント:

  • コードは、まず意図を反映する必要があります。結局のところ、それは人間が読むためのものです。その後、どうしても必要な場合は、パフォーマンスのためにコードを微調整することができます。何よりも、ギミックやちょっとしたハックを示すコードを書くことは決してありません。
  • コードを複数の行に分割しても、パフォーマンスにはまったく影響しません。
  • コンパイラのオプティマイザを過小評価しないでください。できるだけ直観的にコードを書くだけで、オプティマイザーが最高のパフォーマンスを保証します。

この点で、最も説明的で直感的で最速のコードは次のとおりです。

std::swap(a, b);
于 2012-10-13T08:30:38.200 に答える
1

コードを書いたり読んだりするときに、読みやすさとすぐに理解できることは、私が個人的に評価するものです (そして他の何人かが投票するかもしれません)。メンテナンス性が向上します。提供された特定の例では、作成者がこれらの数行で何を達成しようとしているのかをすぐに理解することは困難です。1 行のコード:a=a+b-(b=a);非常に巧妙ですが、作成者の意図が他の人に明らかに伝わりません。

効率の面では、コンパイラによる最適化はとにかくそれを達成します。

于 2012-10-13T08:47:35.480 に答える
0

少なくともJavaに関しては、JVMは通常の単純な使用に最適化されていることを読んだことを覚えています。そのようなことをしようとすると、自分をだますことがよくあります。

しかも見た目がひどい。

于 2012-10-13T08:31:15.777 に答える
0

OK、これを試してください。次回奇妙なバグが発生した場合は、できるだけ多くのコードを 1 行にまとめることから始めます。

数週間待って、それがどのように機能するかを忘れてしまった.

デバッグしてみてください。

于 2012-10-13T08:36:16.753 に答える
0

もちろん、それはコンパイラに依存します。私はどんな種類の驚くべき違いも予見できませんが. 難解なコードがメインです。

于 2012-10-13T08:42:48.067 に答える