Javaの理論と実践: パフォーマンス管理 -- しっかり計画していますか?

最適化で重要なのは方法より時期である

パフォーマンスの問題はどこから発生するのでしょうか。パフォーマンスの問題につながる可能性のあるプログラミング上の選択には、非効率的なアルゴリズム、冗長な計算、不適切なリソースの割り当てと使用、過剰な同期化、そして単に設計自体が非効率的であるなど、さまざまな種類があります。しかし、最も一般的でより大きな被害をもたらす原因は、プログラミングよりも、その管理方法や取り組みにおける誤りです。今回のJava理論と実践では、Java言語を使用したプロジェクトで最もよく見られるいくつかのパフォーマンスに関する失敗について、Brian Goetz氏が説明します。

Brian Goetz (brian@quiotix.com), Principal Consultant, Quiotix

Brian Goetz は18 年間以上に渡って、専門的ソフトウェア開発者として働いています。彼はカリフォルニア州ロスアルトスにあるソフトウェア開発コンサルティング会社、Quiotixの主席コンサルタントであり、またいくつかのJCP Expert Groupの一員でもあります。2005年の末にはAddison-Wesleyから、Brianによる著、Java Concurrency In Practiceが出版される予定です。Brian著による有力業界紙に掲載済みおよび掲載予定の記事のリストを参照してください。



2003年 3月 25日

パフォーマンスの問題は、多くの場合にアプリケーション開発が完了するまで表面化しないため、パフォーマンス管理はしばしば謎の魔法のように考えられます。アプリケーション開発が終了した時点で原因を特定しようとしても、それは非常に困難です。ただし、その原因が十分に明らかであれば、多くの場合、修正は比較的容易になります。一般に、技術者は非常に創造的で (独創的すぎる場合もありますが)、特定の作業をより効率的に実行する方法を発見するのが得意です。どのようなパフォーマンス上の問題も、その解決策は、アルゴリズムをより効率的なものに置き換えたり、キャッシュを使用して冗長な計算を減らしたり、単にハードウェアを追加するなどのように、非常にシンプルである可能性があります。しかし、パフォーマンスの問題の原因 (複数の場合もあります) を明確に特定することは非常に難しい場合もあり得ます。洗練されたプログラムを作成して、最初からパフォーマンスの問題が発生しないようにすることはさらに困難です。

通常、プログラミング上の判断 (完全に最適とはいえないアルゴリズムやデータ表現の選択、前回の計算結果の不十分な再利用、適切でないリソース管理など) は、パフォーマンス上の問題に最も深く関わる原因だと考えられますが、それ以外にもより深い原因が存在します。それは、パフォーマンスの管理、目標設定、および測定を、最初から開発工程に組み入れていないことです。

問題を明確にする

パフォーマンスに問題があることは、どのようにしてわかるのでしょうか。大多数の開発チームは (米国の最高裁判所判事Potter Stewartの有名な言葉を借りて) 「問題が目に見える形で表れたときに初めてそれがわかる」と答えるでしょう。この言葉は問題の核心を突いています。多くの場合、パフォーマンス上の目標、測定基準、および測定は、手遅れになってからしか検討されません。

最も一般的に見られるパフォーマンス管理方針は、実は「何もしないこと」なのです。そして、この方針は、一般に次のいずれかの形をとります。

  • アプリケーション開発が完了するまでパフォーマンスを完全に無視する。
  • 開発しながら最適化を行う。一般に、この方法では細かいパフォーマンスの問題にのみ重点が置かれ、全体的な問題は無視されます。

この2つの計画には、同じ問題が潜んでいます。それは、パフォーマンス管理を開発の一部として開発工程に組み込んでいないことです。

欠陥パフォーマンス計画A: パフォーマンスを完全に無視する

パフォーマンスに問題があることは、どのようにしてわかるのでしょうか。大多数の開発チームは (米国の最高裁判所判事Potter Stewartの有名な言葉を借りて) 「問題が目に見える形で表れたときに初めてそれがわかる」と答えるでしょう。この言葉は問題の核心を突いています。多くの場合、パフォーマンス上の目標、測定基準、および測定は、手遅れになってからしか検討されません。

最初の「パフォーマンスを完全に無視する」という取り組み方法では、パフォーマンスを、リリース・ノートやインストーラーを作成するのと同じように、プロジェクトの最後に処理できるもののように扱っています。基本的には、この計画は運に頼るのと同じことです。コンピューターは年々高速化しているため、この方法でもある程度はうまく行き、それに慣れてしまうのです。

運に頼ることの問題は、たとえそれがどれほど勝算の高い賭けであっても、実際にパフォーマンスに問題が発生した場合、問題に取り組んで原因を特定し、それに対処するための枠組みがなく、場当たり的な方法でしか対応できないことです。またこの計画では、開発計画にパフォーマンスの測定とチューニングのための時間が組み込まれていません。これではまるで、既定の設定によってファイアウォールをインストールしただけで、首尾一貫したセキュリティー・ポリシーを持とうとせず、あとでハッキングの被害にあっていたことを発見するサイトのようなものです。では、どの時点から始めたらいいのでしょうか。

欠陥パフォーマンス計画B: 開発しながら最適化する

もう1つの一般的な、しかもさらに悪い取り組み方法は、細かいパフォーマンス上の考慮点を基にアーキテクチャーと設計を決定する方法です。コードの最適化は満足感が得られる上に楽しいため、開発者はこれが大好きです。しかし、どのコードに重点を置き、開発サイクルのどの時点でパフォーマンスの問題に対処するかという観点から最適化の時期を考えるほうがずっと重要です。残念ながら、開発者は一般に、実際にはアプリケーションのどこにパフォーマンスの問題があるのかについて、あまり優れた直観力を発揮しません。その結果、あまり実行されない部分のコードを最適化することに労力を費やしたり、さらにひどい場合には、最初からパフォーマンスには何の問題もないコンポーネントを最適化するために、優れた設計や開発の慣習を曲げる場合もあります。コードにだけ目を向けていると、パフォーマンスの「木を見て森を見ない」という失敗に陥りがちです。

それぞれのコード・パスをできる限り高速化しても、最終的な製品のパフォーマンスが良くなるとは限りません。各コンポーネントがどれほど高速に実装されていても、部分的な最適化によって根本的に効率の悪い設計を補うことはできません。開発しながら最適化するという計画では、プロジェクト全体を考えたパフォーマンス計画を持つ代わりに、低水準のパフォーマンス上の考慮点に目を向けることになります。さらに悪いことに、プロジェクトの当事者は、それで実際のパフォーマンス計画を持っていると思い込んでしまいます。

開発しながら最適化するという計画には多くの問題点がありますが、その1つは、この方法が最適化にもともと潜むリスクを無視していることです。最適化には、結果としてより優れた設計やバグの減少を可能にするものもいくつかありますが、これらは例外です。ほとんどの場合、最適化にはパフォーマンスとその他の考慮点 (バグのない設計、明快さ、柔軟性、機能性など) とのトレード・オフが伴います。最適化には、バグの発生、コードの機能の制限、コードの使い勝手や保守のしやすさの低下などの危険性や代償がついて回ります。このような代償を払う前に、それに見合うメリットがあるかどうかをよく考えてください。


パフォーマンス管理を開発工程に組み込む

パフォーマンスの測定と計画は、最初の段階から行程に組み込み、開発とパフォーマンスの測定 / チューニングが交互に繰り返し行われるようにするべきです。言い換えれば、パフォーマンスの目的と目標を設定し、適切なパフォーマンス測定計画を立て、コード開発の進展に合わせて頻繁にコードのパフォーマンスを確認するということです。コードの変更に伴ってパフォーマンスがどのように変化したか簡単に確認できるよう、以前のテスト結果を保持しておいてください。データベースへの保存をお勧めします。

開発とパフォーマンス測定を切り離して繰り返すことにより、開発者は、必要であれば後ですぐにパフォーマンスを改善する機会があるとわかっているので、開発の期間中は機能的でバグのないコードを作成することに集中できます。コードを高速化する優れた方法を思いついた場合は、すぐに実装せず、そのアイデアを詳しくコメントに残してください。開発の期間中は、まだ最適化の時期ではありません。パフォーマンスに集中する段階になり、必要であると判明した場合は、そこに戻って実装してください。パフォーマンスの最適化は、パフォーマンス目標を達成することを目的に、パフォーマンス測定値に基づいて実行してください。それ以外はただの「遊び」です。

2回測定してから決断しよう

測定は、パフォーマンス管理の重要な要素です。ある調整によってコードがより高速に実行されるようになるとします。まずは、それを証明しなければなりません。パフォーマンス測定ツールを使って、その調整を行う前と後の両方でテストを実行してください。測定値にパフォーマンスの改善が表れない場合はどうすべきでしょうか。その場合は、調整内容を元に戻してください。メリットが測定値に表れないにもかかわらず、適切に動作しているコードを変更するような危険を冒す必要はないはずです。

パフォーマンスに集中する期間は、アプリケーションまたはそのコンポーネントのパフォーマンスを測定し、前回の測定値と比較します。何かが遅くなっていましたか ? その場合は原因を特定してください。パフォーマンス目標を下回っていなければ、必ずしもその部分を変更する必要はありませんが、原因を知ったことで、変更がパフォーマンスに与える影響について、貴重なフィードバックを得たことになります。

目標は達成されたか ?

定量的なパフォーマンス目標と、それをサポートする測定計画がなければ、パフォーマンス・チューニングはほとんど無意味です。これらがなければ、目標が達成されたこともわかりません。コーディング、テスト、パッケージングなどの他の開発局面には、一定の機能セットの実装や特定のバグの修正など、それぞれに決められた目標があります。パフォーマンスに関する局面にも、同様のしくみや目標が必要です。

外部からパフォーマンスに関する懸念を寄せられている場合、パフォーマンス目標を持つことは特に重要です。これは、相手が顧客であっても社内の他部門であっても同じことです。誰かにプログラムを高速化するように言われた場合には、まず「どの程度高速化すればいいですか」と質問してください。そうでなければ、チューニングに必要以上のリソースを投入しても、顧客がまだ満足しない可能性があるからです。多くの労力を投入してプログラムを30%高速化したにもかかわらず、「本当は50%は速くしてもらいたかった」などと言われては、本当にがっかりすることになります。


まとめ

パフォーマンス管理は、最適化よりずっと重要です。パフォーマンス管理とは、最適化をする場合と、しない場合を決定する枠組みを持つことです。このような決定は、直感に頼るのではなく、明確なパフォーマンスの目標、測定値、および計画に照らして行う必要があります。

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。プロフィールで選択した情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology
ArticleID=218553
ArticleTitle=Javaの理論と実践: パフォーマンス管理 -- しっかり計画していますか?
publish-date=03252003