コンパイラ最適化
不要な計算や計算途中の値を削除する。CPU、キャッシュ、メモリをなるべく使わないようにすることで高速化させる。
ループを構成する文のブロック(例えばfor文)に対して最適化を行う(ループ不変量コード移動など)。プログラムの実行時間の大部分は何らかのループ内であることが多いため、ループ最適化は性能に重大な影響を与える可能性がある。
あるコードがプロシージャを呼び出す場合、そのプロシージャ本体を呼び出し側コード内に展開する。これによりプロシージャ呼び出しのオーバーヘッドを低減し、同時に展開した部分にさらなる最適化を施すことが可能となる。しかし、プロシージャのコードが呼び出し側にコピーされるので、メモリ使用量は増える。一般にインライン展開は小さなプロシージャを何度も呼び出す場合に有効である。
プログラムの動作に影響を与えない命令群(例えば、使われていない定義)などを削除する。これによりコードのサイズを縮小し、不要な計算をしないようにする。
コンパイラは、ある時点ではプログラム全体のごく一部しか見ないのが一般的である。せいぜい1つのモジュールを見る程度であり、一般にはプロシージャ単位でしか見ない。このため、重要な文脈的情報を見落とす可能性がある。
コンパイラ最適化のオーバーヘッドの制約。高度に最適化を行おうとすれば時間がかかる。プロシージャ間の最適化は、そういった意味で非常にコストがかかる。
コンパイラ最適化の各フェーズ間の相互作用。どのようにフェーズを組合わせるのが最適か、どういう順番で行えば時間を節約できるか、という問題がある。
最適化技法を改良する試みは続けられている。1つの試みとして「ポストパス」オプティマイザがある。これは最適化コンパイラの出力である実行ファイルに対してさらに最適化を行うツールである。コンパイラ最適化がプログラムの中間表現に対して作用するのに対して、ポストパス・オプティマイザはアセンブリ言語レベルに対して作用する。しかし、ポストパス・コンパイラにも限界がある。なぜなら、オリジナルのソースコードに存在していた情報の多くは、実行ファイルでは失われているからである。
プロセッサの性能向上はメモリの帯域幅の向上よりも激しい。そのため、たとえ余分な命令を実行しなければならないとしても、使用するメモリ帯域幅を削減するような最適化が有効になってきた。例えば、入れ子ループ最適化や再実体化がそのような最適化の例である。
再帰にはコストがかかる。関数呼び出しはコールスタックを使用し、引数を渡すオーバーヘッドがかかり、命令キャッシュがフラッシュされてしまう。末尾再帰アルゴリズムは単純な繰り返しに変換でき、関数呼び出しのオーバーヘッドを除去できる。末尾再帰除去とも呼ぶ。