パフォーマンスマネージメント - ちゃんと計画している?


Java theory and practice: Performance management -- do you have a plan?の適当訳です。(一部訳を省略しています)


パフォーマンスの問題は何に起因するだろうか?効率の悪いアルゴリズム、冗長な計算、非効率なデザインなどだろうか。
もっとありそうでさらにダメージが大きいのはプログラミングの間違いではなく、アプローチとマネージメントの間違いだろう。


パフォーマンス問題の原因そのものを見つけるのはとても難しい、特定してしまえば直すのは簡単である。さらに難しいのはパフォーマンスの問題のない洗練されたプログラムをデザインすることだ。
アルゴリズムの選択や、データの表現方法、計算結果の再利用の失敗などプログラミングにおける各種決断がパフォーマンス問題の原因と思われがちである。だが実はもっと深い問題を抱えていることがある。それは開発プロセスに、パフォーマンスマネージメント、ゴール、計測を統合できていないことである。

問題?何が問題?

どうやってパフォーマンスに問題があることに気づくだろう?多くの場合その問題を見て気づいたときである。
そしてこれがこの問題の核心部分だが、手遅れになるまでパフォーマンスのゴール、メトリクス、計測は考慮されないのだ。
ありがちなパフォーマンスマネージメント戦略は

  • アプリケーションの完成までパフォーマンスを全く無視する
  • 大きな部分は無視して、とてもちいさい部分などを気の向くままに最適化する

などである。

どちらも開発プロセスにパフォーマンスマネージメントが組み込まれていないという問題を抱えている。

ひびわれのパフォーマンス戦略A:パフォーマンスを全く無視する

この戦略はパフォーマンスを、プロジェクトの最後にうまく扱えるかのように考える。あたかもリリースノーツやインストーラを作るかのようにである。
基本的にこの戦略は運に依存している。


この戦略の問題点は、もし仮にパフォーマンス問題に遭遇してもそれにアプローチするフレームワークがないことである。あるのはせいぜい adhoc な方法だ。
さらにもう一つの問題は開発プランにパフォーマンス計測とチューニングが組み込まれていないことだ。

ひびわれのパフォーマンス戦略B:気ままに最適化する

もっと良くありがちで、さらにもっと良くないアプローチは、小さなパフォーマンス事項を構造やデザイン決定の源としてしまうことである。
プログラマはコードを最適するのが好きなのだ。しかしながら「どのコードにフォーカスすべきか」「開発サイクルのどの部分でパフォーマンス問題にあたるか」のほうがはるかに大事である。
不幸なことに、プログラマはアプリケーションのどこにパフォーマンス問題があるかを知る直感力を持っている。その結果プログラマは滅多に実行されないコードを最適化するのに時間を無駄にしたり、さらに悪い場合には、パフォーマンス問題がないコンポーネントを最適化するために良いデザインをこわしてしまう。
それぞれのコードパスを可能な限り速くしても最終的な製品のパフォーマンスが良いという保証をもたらすものではない。


気ままに最適化する場合の問題点の一つは、最適化に内在するリスクを無視している点である。良いデザインとより少ないバグで行える最適化はごく少数である。
多くの部分では、最適化はパフォーマンスとなにがしかの考慮事項(分かりやすいデザイン、柔軟性、機能性)とのトレードオフを含んでいるのだ。
最適化にはコストとリスクがある。

パフォーマンスマネージメントを開発プロセスに含めよう

パフォーマンス測定・計画は、最初からプロセスに統合すべきである。開発・パフォーマンス計測・チューニングという独立した繰り返しとして統合するのである。
これはパフォーマンスの対象とゴールを決め、適切なパフォーマンス計測プランを立て、開発中にコードのパフォーマンスをチェックすることを意味する。
過去のテストデータを保存しておき、コードを変更したことでパフォーマンスがどう変わったかを知ることが出来るのだ。


開発とパフォーマンスを分けて反復していれば、必要があればすぐ後にパフォーマンス改善の機会があると知っているので開発のタイミングでは機能的でバグのないコードに集中できる。
もしパフォーマンスを向上させる賢い方法を思いついたならばコメントに残し実装はすべきではない。最適化のタイミングではないのだから。もし最適化のタイミングでそれが必要と分かれば戻ってくればよいのだ。

ゴールはある?

もしも定量的なパフォーマンスゴールもなく、それらをサポートする計測プランもなければパフォーマンスチューニングは意味がない。
どうやってそれらが達成できたと分かるだろう?
開発における別のフェーズ、コーディング、テスト、パッケージングには決められたゴールが必ずある。
同様にパフォーマンスフェーズにもゴールを設定すべきなのだ。


顧客や会社の別のチームなど別のところからパフォーマンスについて担当している場合ゴールを決めることは特に重要である。
誰かがあなたのプログラムをもっと速くせよといった場合、”どのくらい速くすべきなのか?”とたずねるべきだ。
そうしないと、チューニングに不必要なリソースを割くことになりさらに顧客はハッピーではないだろう。

サマリ

パフォーマンスマネージメントとは最適化よりもっと良いものである。
それは「いつ最適化するか?」「いつ最適化するべきでないか?」を決定するフレームワークを備えている。
直感に従うのではなく、明白なパフォーマンスゴール、測定、計画の元にこれらの決断をすべきである。

感想

Mosh のパフォーマンスチューニングで多くの失敗をしたおかげでこの文章の本当の意味するところが身をもって理解できたと思います。
またこういう文章を素直に受け取って読めるようになったのも自分的には進歩かな。


なおこの文章は mumurik さんから教えていただきました。ありがとうございます。
彼とはいつか彼が引退する前に一緒にコードを書いてみたいものです。