7
double calcTaxAmount() {
    double price = getA() * getB() + getC();
    double taxRate = getD() + getE();
    return price * taxRate;
}

上記の関数は納税額を計算します。

価格とレートは、他の関数を呼び出すことによって計算されます。

コードの読みやすさを向上させるために、price と taxRate の 2 つのローカル変数を導入したので、両方とも 1 回だけ使用します。これらの種類の「1 回限りの」ローカル変数は、ほとんどの最新のコンパイラでコンパイル時に置換およびインライン化されますか?

4

4 に答える 4

4

一般的にはい。

Java は、コードが何度も呼び出された後 (デフォルトでは 10,000 回) にのみコードをネイティブ コードに最適化します。

それぞれ 1 ns の差があったとしても、2 秒の遅延を追加するには、このメソッドを 10 億回呼び出す必要があります。たった 1000 万回の場合、違いに気付くことはほとんどありません。

于 2012-08-31T15:31:19.713 に答える
4

明らかに、それはコンパイラに依存します。かなりの数のコンパイラは、最適化に関しては実際には頭が死んでいます。これは、ほとんどの最適化が無効であり、他の多くの最適化が非常に制限された条件 (たとえば、任意の関数呼び出しほぼすべての影響を与える可能性があります)。たとえば、すべての Python 実装にはコンパイラが組み込まれていますが、ほとんどの実装ではピープホールの最適化がほとんど行われておらず、すべてのオーバーヘッドを排除するには不十分な場合があります。

そうは言っても、静的に型付けされた言語について話している場合(例が示唆している)、通常はそうです。活性分析は同等性を検出でき (保存場所は必要ですが、有効期間は同じです)、合理的なレジスタ アロケータは不必要に値をこぼすことを避けることができます。

とはいえ、これは最適化にとって非常に悪い焦点です。実際に高速化したい場合は、最終的なコードを見て、現実的なシナリオでプロファイルを作成してください。また、マイクロ最適化を行う場合は、常識を適用してください。この関数がホットスポットであると仮定しても、実際の計算と値の取得には 100 倍の時間がかかります。インライン化されていない関数呼び出しは、スタック ストアに比べてかなり時間がかかり、キャッシュ ミスもこのレベルではかなりコストがかかります。

于 2012-08-31T15:31:32.583 に答える
1

Cのコンパイラに完全に依存します。適切な最適化オプションがオンになっている現在のコンパイラではおそらくはいです。

Javaの場合、コンパイラ(javac)によって最適化されませんが、コードが実際に実行されるときにJITによって最適化される可能性があります。

そうは言っても、これらのローカル変数はとにかくオーバーヘッドをほとんど追加しません。コンパイラが式を次と同等に最適化することを決定した場合:

 return (getA() * getB() + getC()) * (getD() + getE());

部分式の中間結果を格納するには、何らかの形式の一時ストレージ(スタックまたはレジスター)が必要です。とにかく、それは大きな違いを生むべきではありません。

私はそれについて心配することはなく、より読みやすいものを選びます。

于 2012-08-31T16:18:01.617 に答える
1

コンパイラーがそれらがエイリアス化されていないこと、および外部で変更されていないことを証明できる限り、コンパイラーはそれらを最適化して取り除くことができるはずです (そして、ここでそれを判断できると思います)。

それらを作成する場合、それconstを最適化できなかったコンパイラは考えられません。

そうは言っても、これは時期尚早の最適化のように聞こえます。コードが少し遅くなってもコードを変更するつもりはありません。

于 2012-08-31T15:31:49.603 に答える