課題のついでに見積りの練習

| コメント(0) | トラックバック(0)

見積りのむずかしさ

ソフトウェア製品の見積りは難しい。 あるソフトウェア(とまではいかないまでも、何らかのプログラム)を作るのに どれくらいの期間が必要となって、最終的にできあがったものがどの程度の大きさに なるか、ということを見積もることは難しい。 以前から知識としては知っていたけれど、最近だんだんと、その理解が実感を伴うようになってきた。

難しいからといって避けてとおれるわけでもない。

それはそれとして、最近『人月の神話』を読んだ。 実は数年前にも読んでいたけれど、当時はいまいちピンとこないものがあってそれほど印象に残っていなかった。 最近になって翻訳がまずいらしいという噂を聞いて、 せっかくだから原文を読んでみようと思って大学の図書館を当たったのだが、 残念ながら"The Mythical Man-Month"は貸し出し中だった。 隣には新装版の『人月の神話』があって、どうやら追加の章(「銀の弾丸再発射」という洒落たタイトルだった)が あるようだったのでこれを借りてみた。 ひさびさに読むと、これほど思慮深く書かれた本だったのかと驚いた。 当時の自分にはほとんど右から左で、いかに未熟だったかを思い知った。 おそらく今も相対的にはあまり変わってないだろう。

有名なブルックスの法則のほかにも、 興味深い記述がたくさんあったが、特におもしろいと思ったのは 「見積りの精度は経験によってしか向上させられず、 その練習としてこれから書くプログラムの最終的な行数やバイト数を予想してみるのは 試してみる価値のある試みだ」という一節。 たしかに少しずつでも経験を積むことができるし、何より簡単でつまらない課題に、 この予想という要素を加えれば随分とエキサイティングになるような気がした。

テーマとした課題

情報科学類の一年次では、2学期と3学期に「プログラミング入門(I/II)」と呼ばれる C言語によるプログラミングの講義と演習が実施される。 全体をとおしてとてもシンプルな課題が出されるので、見積りの練習には持ってこいだと思う。 残念なのはこれから手をつける課題が学年最後の課題で、 来年はどの講義でこの遊びをすればいいのか今のところ見当がついていないことだ。 まあたぶん何かあるのでそれはいいけど。

課題の内容は小さな有向グラフに関するもので、以下の2つのプログラムと実装せよということだった:

  1. グラフ内の任意のノードから、任意のノードへの最短経路を表示
  2. グラフ内の任意のノードから、任意のノードへのすべての経路を表示

課題には例題が添えられていて、これは概ね(1)の正答に近いものでちょっと残念だったのだけどそれはまあそれとして、 まあそういう問題のそれぞれの成果物についての予想をすることにした。

予想(見積り)

予想のパラメータとして、『人月の神話』では以下のものが挙げられていた:

  • ソースコードの行数
  • バイナリのバイト数

現代にあってはバイナリのバイト数はあまり重要じゃないので、今回は省く。 その代わりに今後は以下の要素を追加したい(今回は小さいので省く)。

  • コード内の関数の数
  • コード内の構造体の数
  • 構造体内での相互参照(再帰的定義)の頻度

これはC言語での用語なので、別の言語でやる場合は適宜読み替える必要がある (言語によってはその重みが異なることがあることが問題かも。一行の余地あり)。

この遊びには僕の他にもう1名参加した(@opentaka)。 結果の比較ができて結構おもしろかった。

今回の課題はとても小さなものだったので、複雑性に関する予想はしないことにした。

予想と結果、その誤差を次の表にまとめた。うーん。

予想 結果 誤差
課題1 150行 82行 68行
課題2 180行 53行 127行

結果との乖離

行数レベルでの具象的見積りはこれがはじめてだったので、 誤差の行数が大きいか小さいかについては判断の材料を持たない。 個人的にショックだったのは、課題2の行数が課題1の行数を下回ったことだ。

実は見積りを立てる段階で「課題2のほうが課題1よりも小さくなるのではないか」 という仮説も一度立てていた。課題2はすべての経路、課題1は最短経路であり、 課題1を含む問題じゃないだろうかと判断してのことだったのだが、 最終的には「課題1のソースコードに追加の記述をして課題2を解くことにしよう」 と考え、課題2の行数を課題1よりも大きく見積もった。

実際には課題2のコードは課題1とはほぼ別個のコードとなった。

課題1で用いた最短経路を表示する関数 show_trace は、その内部で 最短距離を手がかりとして記述している(さらに具体的にいえば、 最短経路の内もっとも自分自身に近いノードを返す関数を再帰的に呼んでいる)。 そのため最短経路に限らずすべての経路を表示する課題2の要求には この関数は再利用さえできず、そういうわけでまったく別のコードを書くことになった。

この誤算の最大の原因は前述した「課題2のほうが課題1よりも小さくなるのではないか」 という推測だと思う。一見すると課題2は課題1を包含するようにみえるけど、 実際にはそうではなかった、ということでプロトタイプの作成によって回避できる 典型的なパターンなので、結構残念。

見積りの段階で実装手法まで考えるべきなのかなあ。 プロトタイピングって見積りの範疇なのだろうか?

感想

シンプルにいって結構おもしろかった。若干不純かもしれないけど、 見積もった行数になるべく近づけようという謎の意識も働いて、 単純なワンライナー化とか難読化よりも個人的には知的興味をくすぐられるかもしれない。

来年もコードを書ける演習を含む講義があったらこの遊びをやるかー。

トラックバック(0)

トラックバックURL: http://www.tnzk.org/mt/mt-tb.cgi/306

コメントする

このブログ記事について

このページは、tnzkが2010年3月 1日 18:23に書いたブログ記事です。

ひとつ前のブログ記事は「オープンソースカンファレンス 2010 Tokyo/Spring に参加」です。

次のブログ記事は「JavaScriptでSVGのレーダーチャートを描画するライブラリ Raphael Radar をつくった」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

Powered by Movable Type 4.32-ja