web-dev-qa-db-ja.com

コードの最適化を改善するために、ローカル変数にconstを使用する必要がありますか?

次のように、変更されていないローカル変数にはconstをよく使用します。

const float height = person.getHeight();

コンパイルされたコードが潜在的に高速になり、コンパイラーがさらに最適化できるようになると思います。または私は間違っています、そしてコンパイラはローカル変数が決して変更されないことを彼ら自身で理解することができますか?

33
Frank

または私は間違っています、そしてコンパイラはローカル変数が決して変更されないことを彼ら自身で理解することができますか?

ほとんどのコンパイラは、これを自分で理解するのに十分賢いです。
マイクロ最適化ではなく、const-correctnessを保証するためにconstを使用する必要があります。
constcorrectnessは、コンパイラーが正直な間違いを防ぐのに役立つので、可能な限りconstを使用する必要があります保守性の理由愚かな間違いをしないようにする

私たちが書いたコードのパフォーマンスへの影響を理解するのは良いことですが、過度のマイクロ最適化は避けるべきです。パフォーマンスに関しては、以下に従う必要があります。

80-20ルール:

リソースの20%を使用するコードの80%を特定します。プロファイリングを通じてon代表的なデータセットそして、それらのボトルネックを最適化しようとします。

43
Alok Save

このパフォーマンスの違いはほぼ確実に無視できますが、コードのドキュメント化の理由から、可能な限りconstを使用する必要があります。多くの場合、コンパイラーはとにかくこれを理解し、自動的に最適化を行うことができます。 constは、パフォーマンスよりもコードの可読性と明快さを重視しています。

12
Oleksi

関数パラメーターを含むローカル変数をデフォルトで定数にするのは良い習慣ではないと思います。

主な理由は簡潔さです。優れたコーディング手法により、コードを短くすることができますが、これはできません。

まったく同様に、関数宣言にvoid foo(void)を記述できます。また、関数にパラメーターを渡さないことなどを明示することで、明確にすることで正当化できますが、本質的にはスペースの無駄です。 、そして最終的にはほとんど使用されなくなりました。どこでもconstを使う傾向にも同じことが起こると思います。

ローカル変数をconst修飾子でマークすることは、作成したコードを操作するほとんどの共同作業者にとってあまり役に立ちません。クラスメンバー、グローバル変数、またはポインターが指すデータとは異なり、ローカル変数には外部効果がなく、ローカル変数の修飾子によって制限されたり、ローカル変数から有用なことを学んだりすることはありません(ただし、彼はローカル変数がある特定の関数を変更しようとしています)。

彼があなたの関数を変更する必要がある場合、タスクは通常、そこにある変数の定数修飾子から貴重な情報を推測しようとすることを彼に要求するべきではありません。関数はそれほど大きくなく、理解しにくいものであってはなりません。もしそうなら、おそらくあなたはあなたのデザインにもっと深刻な問題を抱えているでしょう、リファクタリングを検討してください。 1つの例外は、いくつかの筋金入りの数学計算を実装する関数ですが、それらの場合は、コメントに詳細または論文へのリンクを含める必要があります。

あなたは尋ねるかもしれませんそれがあなたに多くの労力を要しないのなら、なぜまだconst修飾子を入れないのですか。残念ながら、そうです。すべてのconst修飾子を配置する必要がある場合は、完了後に関数を実行して修飾子を配置する必要があります。これは時間の無駄です。その理由は、メンバーやポインターが指すデータとは異なり、ローカル変数の使用を慎重に計画する必要がないためです。

それらはほとんどが便利なツールであり、技術的には、それらを式に分解するか、変数を再利用することで回避できます。したがって、これらは便利なツールであるため、特定のローカル変数の存在自体は単に好みの問題です。

特に、私は書くことができます:

  • int d = foo(b) + c;
  • const int a = foo(b); int d = a + c;
  • int a = foo(b); a += c

各バリアントは、変数aが定数であるかどうか、またはまったく存在しないことを除いて、すべての点で同一です。いくつかの選択を早期に行うことは困難です。

0
user10038625