最適化 (情報工学)
プログラムとは別のレイヤ、例えば、コンピュータ・アーキテクチャに原因があることもある。
アーキテクチャに関わる設計はシステムの性能をほとんど決定づける。アルゴリズムの選択は設計の中でも最も効率に影響が大きい。複雑なアルゴリズムやデータ構造は多量の処理には適しているが、単純なアルゴリズムは少量のデータ処理により適している。複雑なアルゴリズムでは設定や初期化に時間がかかり、データが少量の場合に効果が薄れるためである。
場合によっては、メモリを追加することでプログラムが高速化されることがある。例えば、フィルタは入力を1行ずつ読み込んで、結果を即座に出力する。この場合、1行を読み込むだけのメモリがあれば十分だが、そのような方式での性能は一般にあまりよくない。ファイルを一括して読み込めば性能が劇的に改善されるが、メモリをより多く消費することになる。計算結果をキャッシングするのも効果的だが、同様にメモリ使用量が増大する。
計算処理には効率の異なる複数の実行方法が存在することが多い。例えば、以下のC言語のコードは、1 から N までの整数の総和を計算するものである。
演算でのオーバーフローが発生せず、かつ、N >= 0 ならば、これを以下のような数学的な式で書き換えることもできる。
最適化(特に自動的に行われる最適化)は、機能的に等価でより効率的な方法を選択することに他ならない。しかし、効果の大きい性能改善は無駄な機能を省いて実際の問題に集中することで実現されることも多い。
最適化は必ずしも自明で直観的なものとは限らない。上の例で「最適化」されたバージョンは N が小さければオリジナルよりも性能が悪い可能性がある。これは、そのコンピュータでの加算とループの性能と乗除算の性能の関係に依存する。
最適化ではボトルネックを見つける必要がある。ボトルネックとは、化学反応における律速段階などのアナロジーで説明されるが(反応速度#律速段階も参照)、全体を「流れ」とした見た時に最もその流れが妨げられていて、全体の速さがその部分の速さで決まっている、という部分のことである。また近年のように並列実行のコストが下がっている場合、最適化に苦労するよりも問題が並列化可能であるならそちらで解決したほうが手っ取り早いということもある。並列化に関する法則としてはアムダールの法則やグスタフソンの法則がある。
またボトルネックに関する経験則として、全体の1%〜25%のコードが75%〜99%のリソース(CPU時間、メモリ)を消費する(パレートの法則も参照)、といったような傾向がある(当然、ザルに書いたコードほどその傾向は激しく、予めよくわかっている対象について綿密に計画され、さらに改良が重ねられたコードであれば逆になる)。 ボトルネックとなっている処理が非常に単純でそれ以上最適化しようがない場合もある。