2017-01-31 4 views
0

この質問は純粋に好奇心ではなく、私は答えがコンパイラに依存していると確信しています。これは極端なマイクロ最適化でもあり、ほとんど確実に維持できないコードにつながります。 CPUは明らかに各計算を実行してそれをどこかに格納する必要があります。多分それは機能的に同じです。単一行の文は高速ですか?

これまでのところ、変数の使用量を減らしても本質的に高速の実行コードが得られるのではないかという疑問がありました。例えば、長い計算のためにレジスタに結果を残すことを知っているでしょう。もちろん、同じ結果が複数回必要な場合は、これは役に立ちません。例えば

このコード:このような何かのコンパイラの出力は、なしの変数を持つ単一の行、常に同一である一般に

var final = GetFinal((GetNumber() + 10)/2); 

var result = GetNumber(); 
var adjusted1 = result + 10; 
var adjusted2 = adjusted1/2; 
var final = GetFinal(adjusted2); 

は以下に変換することができます言語間で?上記のステートメントが100の計算に関係する場合、それは同じですか?

+0

[アセンブリコードを確認してください](http://stackoverflow.com/a/137074/2721883)の両方が発行されました。 – clcto

+0

それは本当です。しかし、私は一般的なケースではさらに疑問に思っています。 – Telavian

+1

答えはありません。たとえば、純粋な関数と遅延評価関数を持つ言語では、 'GetFinal'の1行引数は使用されないと評価されないかもしれませんが、4行バージョンは評価されます。これはコンパイルを検討する前でも(+が算術プラスを意味しない言語)コンパイルすると、すべてのコンパイラーは、それが準拠していてそのような最適化が強制されない限り、その実装を自由に行えます。一般的に、マクロ最適化を行い、コンパイラにマイクロ最適化をさせ、疑わしいときは読みやすさに焦点を当てます。 –

答えて

2

質問は実際には言語固有ではなくコンパイラ固有です。また、任意の言語はコンパイラをいくつでも持つことができますが、まだ書かれていないものもあります。一般的な答えは不可能です。

ほとんどのコンパイラは、可能であれば、不要なローカル一時変数を自動的に削除します。当然のことながら、値は渡すときのどこかに格納する必要がありますが、プログラムの後半で参照されない限り、メインメモリに格納する必要はないかもしれません。この最適化は比較的簡単なので、どのような最適化を行うコンパイラでも実行することが期待されます。

コンパイラがここで最適化しなくても、ハードウェアはストアを並行して実行すると役立ちます。コンパイラがメインメモリに値を書き込み、すぐに読み込んだとしても、プロセッサはおそらくキャッシュからそれを取得しますが、これはレジスタアクセスよりわずかに遅くなります。

言語のセマンティクスがイントロスペクションまたは実行時解釈を許可するため(たとえば、組み込み関数evalを使用するなど)、変数が神聖であるためにこの最適化が禁止される言語があります。その場合、イントロスペクションや動的評価を使用して参照する可能性があるため、変数は視覚的に参照されていなくても存在する必要があります。つまり、変数を作成することは、何らかの永続的なデータ構造の中に名前を格納することを意味するため、簡単な操作ではありません。しかし、このタイプの言語はほとんどコンパイルされないので、プログラム全体が、余分な変数のコストよりもはるかに重要な解釈オーバーヘッドに苦しんでいる可能性があります。

全体として、わかりやすい方法でプログラムを書く必要があります。それはバグを避け、他の人があなたのコードを理解するのを助け、コンパイラが最適な最適化を見つけるのを助けるでしょう。それは、ほとんど最適化の細部について心配する脳の努力の有用な支出となることはほとんどありません。代わりに、各タスクに最適なアルゴリズムを見つけることに集中します。

+0

確かに脳の努力が重要です! :) – Telavian

1

上記の言語とコンパイラに応じて、コンパイラはコードを最適化します。今日の世界では、あなたの例の違いに気付かないでしょう。さらに重要なことは、コードの保守性と可読性です。アルゴリズムの開発や数十万回の反復、またはミリ秒ごとにカウントされる組み込みプロセッサでは、後者を行うことで多くの利点を得ることはできません。分岐予測とキャッシュミスは異なる場合があります。

関連する問題