25章 コードチューニング戦略
akht.icon25.3まで
1960年代:コンピュータリソースが非常に限られていたので、効率性がとても重要
1970年代:コンピュータの性能が良くなってくると、プログラマはパフォーマンス一辺倒の姿勢がいかにコードの可読性や保守性を損なっているかに気付き、コードのチューニングはそれほど重視されなくなった。
その後も歴史は繰り返す...
本章の内容
パフォーマンスとは何か?
どれくらい重要か?
達成するための一般的なアプローチは?
25.1 パフォーマンスの概要
品質特性とパフォーマンス
顧客はコードの品質や効率なんて気にしてない、実際に関心があるのはプログラムの特性の方
具体例:メモリカードリーダーの話
パフォーマンスはコードの速度とそれほど関係していない。コードの速度に取り組めば、その分だけ、他の品質特性に取り組んでいないことになる。コードを速くするために他の特性を犠牲にしないように注意しよう。コードの高速化に取り組んだことが、かえって全体的なパフォーマンスを損なう結果になることもある。
パフォーマンスとコードチューニング
速度とサイズのどちらに重点を置くか?それを決める前にこれらを検討すること
プログラムの要求
パフォーマンスの前に、解決すべき問題を解決してるか確認する
応答時間について数百ミリ秒を要求していたらユーザーは4秒で満足というのはあるあるっぽい tommy.icon
プログラムの設計
コードチューニングでは解決しづらく、設計レベルで対処しないといけない問題もある
パフォーマンスを優先するような設計にしてから個々のサブシステム、機能、クラスのリソース目標を設定する
リソース目標を個別に設定すると、システムの最終的なパフォーマンスを予測できるようになる
目標を明示的に掲げるだけでその目標が達成される可能性が高まる
良い tommy.icon
効率が徐々に良くなっていくような目標を立てることもできる(例えば、変更を柔軟に行えるようにする、とか)
クラスとルーチンの設計
データ型とアルゴリズムの選択
オペレーティングシステムとのやり取り
システムコール、IO
コードのコンパイル
ハードウェア
最も安価で最良の方法
コードチューニング
チューニング = 1つのクラス、1つのルーチン、または数行のコードに作用する小規模な変更
25.2 コードチューニング入門
コードチューニング != もっと効果的な手段
アーキテクチャ、クラス設計、アルゴリズムの選択の方が大きな改善をもたらす
コードチューニング != 最も簡単な方法
新しいハードウェアを買ったり、賢いオプティマイザがついてるコンパイラを使った方が簡単
コードチューニング != 最も安価な方法
手作業でコードを調整するのは時間がかかるし、調整したコードを保守するのは難しい
コードチューニングの魅力とは?
自然の方法をものともしないこと
コードを数行調整しただけで20ms -> 2msにすることが可能
効率の良いコードを書くコツをマスターすることが、優秀なプログラマになるための登竜門であることも、魅力の1つ
得点にならなくてもテニスボールを拾い上げる作法は覚えないといけない
コードチューニングの問題点
効率的なコードが必ずしも「良い」コードではないこと
25.2.1 パレートの法則
「成果の80%は作業の20%から得られる」
「80対20の法則」とも
いろんなん報告がある
プログラムの実行時間の80%は20%のルーチンによって消費される
プログラムの4%未満が実行時間の50%以上を占めている
「最善は善の敵」完璧さを追求すると、完成にたどり着けないことがある。まず完成させてから、完璧なものにする。完璧でなければならない部分は通常わずかである。
25.2.2 過去の定説
高級言語のコードの行数を減らすと、コンパイル後のマシンコードの速度やサイズが改善される──うそ!
高級言語のコードの行数とプログラムの最終的なサイズや速度との間に断定できるような関係はない
ある種の演算は、おそらく他の演算よりも速いまたは小さい──うそ!
必ず計測する
コードを書くそばから最適化すべきだ──うそ!
早まった最適化は諸悪の根源
プログラムが完全に動かないうちにパフォーマンスのボトルネックを特定することはほぼ不可能
ボトルネックに過剰反応して他の部分を悪化させてしまう
最初から最適化に重点を置くと、プログラムの他の目標を達成できなくなる
速いプログラムであることは正確なプログラムであることと同じくらい重要である──うそ!
正確さ > 速さ
25.2.3 いつチューニングするか
高品質な設計
プログラムを正しいものにする
モジュール化して、変更しやすくしておく
リファクタリング本でもリファクタリングすることで変更箇所が局所化してパフォーマンス最適化しやすくなるって書かれてたなぁ tommy.icon
プログラムが完成し正しいことがわかったらパフォーマンスをチェックする
Jacksonの最適化の法則
法則1:最適化しない
法則2:まだ最適化しない──完全に明白で最適化を使用しない解決策が見つかるまでは(上級者向け)
─M.A.Jackson
25.2.4 コンパイラによる最適化
コンパイラの最適化を最大限引き出すには、シンプルにコードを書くのが大事
雑談
tommy.icon 25.3から
25.3 脂肪や糖蜜の類
25.3.1 非効率の一般的な原因
入出力処理
基本はメモリを選択
「短すぎて測定できなかった」笑う tommy.icon
月の満ち欠けってジョークなのか…? tommy.icon
この本時々伝わりづらいジョークある tommy.icon
ページング
システムコール
インタープリタ言語
この実行時間の表は今だともっと改善されてそう tommy.icon
エラー
25.3.2 一般的な処理の相対コスト
表25-7
ルーチン呼び出しは現代では気にするなってリファクタリング本で言ってたなぁ tommy.icon
細かすぎてあんま役に立たない表な気がする tommy.icon
25.4 測定
チューニング失敗例を見ると細かすぎるパフォーマンス・チューニングのために読みやすさを犠牲にすることはどうなんだろって思うな tommy.icon
読みやすいことでパフォーマンス・チューニングがやりやすいという意味もあるだろうし tommy.icon
25.4.1 測定は正確に
25.5 繰り返し
コードチューニングとコードの品質との関係は、概してこうなるようだ
ほんとかなぁといった感じ tommy.icon
読みやすくてもパフォーマンスのいいコードというのはあるんじゃないか tommy.icon
読みにくい部分は隠蔽化すれば良い気がするし tommy.icon
25.6 コードチューニング手法のまとめ
一度に1つずつ、というのが大事そう tommy.icon
25.7 参考資料
25.8 まとめ
具体的な改善方法はあまり踏み込んでいない章だったなという印象 tommy.icon
次の章で具体的なテクニックが出てきそう