最適化 (情報工学)
これについて Charles Cook は次のように述べている。
「賛成だ。コードのボトルネックがどこなのかが判明する前に細かい最適化に時間を費やすのは無駄だ。しかし逆にシステムレベルのソフトウェアを設計するときは、性能問題を常に念頭に置くべきだ。よいソフトウェア開発者はこれを自動的に行っており、どこの性能が問題となるかを感覚的に感じ取ることができる。経験の浅い開発者は、後の工程でのちょっとした微調整で問題が全て解決するという間違った信念を持っていることがある」
「時期尚早な最適化」という言葉は、プログラマが個々のコードの設計時に性能への考慮をすることを指している。そのような小手先の最適化を最初から行っていると、コードが複雑化してその機能の本質を見誤り、コードが汚くなったり、バグを作りこんだりする。
よい手法とは、設計をまず行い、その設計からコードを書き、プロファイル/ベンチマークを実施して最適化すべき箇所を特定することである。単純で簡潔な設計であれば、この手法での最適化が容易であり、プロファイリングによって予想外の性能問題(時期尚早な最適化では思いもよらなかった問題)が明らかとなることもある。
実際には、ソフトウェアの設計の初期段階から性能目標を念頭に置く必要があるが、プログラマは設計目標と最適化のバランスを保つ(最適化での伸びしろを考慮してコードを書くときの時期尚早な最適化を控える)。
最適化はコンパイラで自動的に行うこともできるし、プログラマが自ら行うこともできる。局所的な最適化の効果は限定的であり、大域的な最適化の方が効果が大きい。一般に、より優れたアルゴリズムやデータ構造を見出すことが最も強力な最適化となる。一方、組込み用途のようにアクセス先がI/Oアドレスにマッピングされている場合、最適化の結果としてアクセス順序が入替えられると組込み機器としては問題が発生する可能性がある。そのような場合、volatile キーワードを付与することで、アクセス順序の入替を抑制することが可能である。
システム全体の最適化は自動化するには複雑すぎるため、人間の手で行うことが多い。その場合、プログラマやシステム管理者が自らコードを修正し、性能を改善する。効率が改善されるとしても、自動最適化に比べれば遥かにコストを要する作業である。
第一にリソースを最も多く消費している箇所(ボトルネック)を見つけるため、プロファイラを利用することが何よりも重要である。プログラマはボトルネックがどこか正確に把握していると思っているものだが、そのような予測は間違っていることが多々ある。重要でないコードの最適化は全体性能に与える効果が少ない。
ボトルネックを特定したら、まずそのプログラムで使われているアルゴリズムを再考するところから最適化が始まる。通常、汎用的アルゴリズムよりも特定の問題に特化したアルゴリズムの方が調整しやすい。例えば、大きなリストをソートする処理では、効率のよい汎用アルゴリズムの1つであるクイックソートを使うのが一般的である。しかし、ソート対象の性質が判っていれば(例えば事前に何らかの順番で並んでいるなど)、その他のアルゴリズムや特製のソートルーチンの方が有効な場合もある。