3

世紀の質問?基本的に、このコードをいくつかの異なる変数として記述した場合、または小さな配列を使用した場合に、どちらがより効率的かを知りたいと思います。

int x = 34;
int y = 28;
int z = 293;

vs

double coordinate[3] = {34, 28, 293};

次のように使用する座標構造体があります。

typedef struct coordinates_t {
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;

} coordinates;


typedef struct car_t {
    coordinates start; // car starting point
    coordinates location; // car current Location
    coordinates targCarVector; // Vector to car from target
    coordinates altitude; // Altitude of car
    coordinates distance; // Distance from car start to current position
} car;

私は次のようなことをする必要があります:

distance = car1.location - car1.start;

配列を使用しない場合は、多くのコード行が必要になりますが、配列を使用する場合は、ループを使用する必要があります。アレイとループはより多くのメモリ/CPUを集中的に使用しますか?私は基本的に、このコードを書くための最も効率的な方法を見つけようとしています。

ありがとう、DemiSheep

4

12 に答える 12

21

保守性や読みやすさよりも効率の方が重要ですか?答えはいいえだ。タイムクリティカルなアプリケーションを使用している場合でも、90%の時間をコードの10%未満で費やすため、10%だけを可能な限り効率的にコーディングする必要があります。

どの10%が原因であるかを測定して見つけていない場合は、そもそも実行時間の少ないコードを最適化することはほぼ間違いありません。これは時間の無駄です。

于 2010-08-27T17:25:59.610 に答える
10

最初の質問は次のとおりです。それを最適化しますか?おそらく、あなたはしたくないでしょう。少なくとも、「コードを維持することになった人が、あなたがどこに住んでいるかを知っている暴力的な精神病質者であるかのように常にコードを書く」場合はそうではありません。読みやすさ、意図の明確さ、保守性が常に最優先されます。

2番目の質問は次のとおりです。最適化する価値はありますか?ドナルド・クヌースによれば、97%ではそうではありません-そしてあなたはクヌースに質問しませんか?もう1つの一般的な経験則は、80/20の法則です。つまり、実行時間の80%がコードの20%に費やされます。最適化する場合は、最初にプロファイルを作成して、最適化する場所を確認します。あなたが推測するなら、あなたは間違っています。限目。

3番目の質問は:それを最適化できますか?いいえ、できません。少なくともこれは簡単ではありません。何十年にもわたってコンパイラーを作成した何百人ものプログラマーよりも賢いと思いますか?あなたは違います。アルゴリズムとデータ構造の実際の実装を最適化できる場合は、コンパイラーがそれを独自に実行できると想定できます。コンパイラーは、ループの展開、命令の並べ替え、重複しない有効期間を持つ変数の組み合わせ、構造体レイアウトの最適化などを実行できます。この時代では、ほとんどの場合、ほとんどのアセンブリープログラマーよりも優れています。そして、少しの可能性があるとしても、より良いアルゴリズムの実装に集中するほうがよいでしょう。O(n ^ 2)をO(n log n)に変換できるコンパイラはありませんが、おそらく賢いコンピュータ科学者がそれを実行し、彼のアルゴリズムを実装して、マイクロ最適化よりもはるかに優れたパフォーマンスを得ることができます。

于 2010-08-27T17:37:15.980 に答える
7

これを実行するプラットフォームごとに測定する必要があります。

ただし、これによって目立った違いが生じることはまったくないと思います。(一部の組み込みプラットフォームを除いて、それは私があまり知らない領域です。)したがって、最初に、最も読みやすく理解しやすい方法でコードを記述します。次に、コードの速度が低下しているかどうかを測定し、プロファイラーを使用して、プログラムが多くの時間を費やしている正確な場所を見つけます。次に、それらを改善し、各変更後に測定して、どの効果があったかを確認します。

理解しやすいコードベースの速度を向上させることは、時期尚早で不要な「最適化」に満ちたコードベースを理解するよりもはるかに簡単です。

測定可能な実行時の改善は、通常、このようなマイクロ最適化からではなく、アルゴリズムの変更からもたらされます。より良いアルゴリズムを見つけるために時間を費やしてください。

于 2010-08-27T17:26:59.017 に答える
3

これを本当にマイクロ最適化したい場合は、CPUのSIMD命令機能を使用してください。x86プラットフォームを使用している場合は、座標の各部分を個別に追加する代わりに、MMXまたはSSE命令を使用してベクトル演算を実行できます(コンパイラは、特別なコマンドラインスイッチまたはインラインアセンブリなしではこれらを生成できない場合があります)。これはおそらく、個々の変数と配列を切り替えるよりも大幅に高速化されるでしょう。「たぶん」と言うのは、両方の方法を試し、実行時間を測定しなければ、確実に判断する方法がないからです。

于 2010-08-27T17:48:37.397 に答える
2

配列を使用し、-funroll-loopsを使用してコンパイルします。両方のメリットがあります。

于 2010-08-27T17:26:57.063 に答える
2

コンパイラーは、ループが役立つと考えれば、ループを「展開」できます。したがって、コンパイラは次のコードを静かに置き換える可能性があります。

for (i = 0; i < 3; ++i) {
    c[i] = a[i] - b[i];
}

と:

c[0] = a[0] - b[0];
c[1] = a[1] - b[1];
c[2] = a[2] - b[2];

コンパイラーは、関連する操作のコストと提供する最適化フラグを考慮して、これを行う価値があるかどうかについて最善の推測を行います。

「どちらが速くなるか」に対する簡単な答えはありませんが、もしあれば、最大限の最適化でコンパイラがそれを使用することを確信できます。

于 2010-08-27T17:27:30.373 に答える
1

疑わしい場合は、それぞれのプロトタイプをコーディングしてプロファイルを作成します。このレベルのものについては、パフォーマンスの違いがノイズで減少すると予測します。意味があり、デザインの意図を最も明確に伝える ものを使用してください。

重要度の高い順に、コードは次のようになります。

  1. 正解-コードが間違った答えを出したり、間違ったことをしたりしても、コードの速度は関係ありません。
  2. 保守可能-コードを修正したり、新しい要件に対応するように変更したりできない場合でも、コードの速度は関係ありません。
  3. 堅牢-危険な入力の最初のヒントをコアダンプする場合、コードの速度は関係ありません。

この後どこかで、パフォーマンスについて心配し始めることができます。

于 2010-08-27T17:33:13.543 に答える
1

世紀の答えは

カートを馬の前に置かないでください。

つまり、最初にプロファイルを作成します。

誰もがこれを「知っています」が、SOに関する質問の大部分は、「XとYのどちらが速いか」という形式です。

これは推測を引き出します。パフォーマンスが心配な場合、推測はあまり価値がありません。パフォーマンスの問題がある場合は、おそらく完全に別の場所にあるからです。

于 2010-08-30T15:55:36.320 に答える
1

私は通常、効率について心配しません...

処理速度が上がる場所の1つは、数値を検索する場合、アカウント番号「188335344」を検索すると、英字を検索するよりもはるかに高速になります。検索では、数値以外の値を検索するため、テキストの各行を大文字に切り替える必要があります。数字はそうではありません。

実際にはかなり高速です。

ユーザー入力を必要とするものはすべて非常に非効率的である可能性があり、イオタは問題ではありません。

各検索の最後に経過時間を表示します。したがって、古いコードを最近の変更と比較できます。

于 2016-08-20T16:27:38.473 に答える
0

いつものように、確実にコードをプロファイリングする必要があります。

そうは言っても、配列とループを使用することをお勧めします-コードはより簡潔で保守しやすく、コンパイラーはすべての小さな一定サイズのループを最適化/展開できるようにする必要があります。これは事実上何ですかすべてのベクトルにx、y、z座標を使用した場合は、手作業で行うことになります。

まったく関係のないメモで、私はあなたの車が高度を持っているのを見ます。空飛ぶ車ですか?もしそうなら、クールなアプリケーションのために間違いなく+1。

于 2010-08-27T17:26:25.063 に答える
0

より正確な方法(ループと配列を使用する方法)を選択してください。どちらもメモリ使用量は多くなりません(car1、car2、car3 ...のすべての命令で必要なメモリが増えるため、使用量は少なくなります)。CPU使用法に関しては、ごくわずかな違いを見ています。

于 2010-08-27T17:29:09.240 に答える
0

コードのプロファイルを作成し、非効率性の主な問題を見つけてください。効率は、コードの実行時実行によって測定できます。

そのためのいくつかのツールは、 gprofのようなオープンソースとして利用できます。

于 2010-08-27T19:59:58.320 に答える