« 文字というメディアの優位性 | top | ソクラテス・スコア »

2006年09月30日

タスクスイッチのコストを下げる10の方法

いくつのプロジェクトの作業を並行にできるか?
小さな組織では、これは重大な問題だ。

The Multi-tasking Mythを読んで考えた。

プロジェクトの「かけもち」は、タスクスイッチングのコストがかかるので、
全体として効率が上がるわけではないということは、誰でも何となく知っていることだ。
ソフトウェア開発者ならば、マルチタスクOSをいじっているから、
コンテキストスイッチのコストが高いことは、感覚的に知っている。

Joel氏なども言うように、プロジェクト数が問題なのではなく、
仕事の内容がタスクスイッチのコストを決める。作業のために必要な短期記憶の量が、
プログラミングに関しては非常に多いので、タスクスイッチのコストが高いというのである。
逆に、仕様書作成、プロジェクトマネジメント、さらにそれをとりまとめる仕事など、
抽象度の高い仕事になるにつれ、短期記憶の量が少なくて済むので、
マルチタスクがやりやすい。
経験的には、プログラミングの作業が、最もタスクスイッチしにくい。

Joel氏はプログラミング作業に必要な短期記憶の内容を以下のように列挙している。
変数名、データ構造、 APIの使い方、便利関数の名前、ファイル名。
他にもポート番号やマシンの名前やIPアドレスやURLや一時的につけたコメントの位置、
特定のバイト列やコンパイルオプション、IDEのキーバインディングや
デスクトップに置いてある作業ファイルの内容、読みかけの技術書のページ番号など、
挙げていくと相当な量になるだろう。(これを全部列挙するというのも是非やってみたい。)
しかもこれらのリアルタイムな作業情報は、ドキュメント化されないことがほとんどだし、
ドキュメント化するにはコストが高すぎる。
プログラマは、ドキュメントに書かれていない大量の短期記憶に基づいて仕事をする。

ソースは忘れたが、一説によると、1人のプログラマがコントロールできるコードの量は、
1万5000行程度だという。ただしこれは変更中の「ホットな」コードの量であって、
過去に書いた安定したライブラリのようなものであればこの範囲に入らない。
ホットなコードが1万5000行までというのは、私の経験とも一致するし、納得がいく。
もちろん、エンジニアの記憶力などにもよると思うが、
10万行をコントロールできる人はいないだろうし、
1000行しかできないという人もいるかもしれないが採用はしないだろう。
だいたい、数千から1、2万行 といった具合になるのだろう。

タスクスイッチのコストを下げるには、タスクスイッチしないようにする以外にも、
いろいろな方法があるはずだ。
ここはどの程度議論されているのだろうか。まず10個考えてみた。

1.開発に必要なコードやドキュメントの量を少なくする。
Cで書くところをC++にする。C++のところをRubyにする。Rubyのところを
独自開発のDSLにする。 generative programmingをとことんやる。
下位の言語についてできるだけ完全に忘れられる環境を作る。
そのためにDSLのテストを非常に厳しく実行する。たとえば私たちはもはや
86アセンブリのこまかなtipsはほとんど忘れているはずだ。

2.プログラムのレイヤー化を徹底的に行う。
「ホットなコード」を減らせば良いのだから、プロジェクトのコードの大部分が
ホットでないコードであるようにしたらよい。オブジェクト指向はその指針になるだろう。
徹底的にオブジェクト指向を実践するのだ。モジュールを美しく設計して、
その中身のコードを完全に忘れても大丈夫な状況を作る。

3.テストやビルドなどを自動化する。
この部分の操作方法は、短期記憶に入れるにはもったいない。
くりかえしやる作業を短期記憶に入れるのは無駄だ。
また開発中のホットなコードをテストするために必要なデータの量や配置を
最小限にすることも有効だろう。
さらにテストやビルド専用の担当者がいたら、その部分を外に出せる。
組織全体の水平分業化は、これを助ける。ただし、まったくちがうプロセスを
導入したくなったときにはコストアップする可能性もある。

4.仕様書を作成する人に、質の高い仕事をしてもらう。
より少ない量で仕事内容を定義できる仕様書を書くようにしてもらう。
さらに質の高い仕様書を書くためには、その一段階上のビジネス上の
要求定義をするときに、その品質が高い必要があるだろう。
プログラマのタスクスイッチのコストを下げるために、他の担当者もできることがあるということだ。

5.スイッチするプロジェクト同士の関係を調整する。
Ruby のプロジェクトから Pythonのプロジェクトにスイッチする場合と、
Ruby のプロジェクトから Rubyのプロジェクトにスイッチする場合とでは、
共通に使える短期記憶が多いので、後者のほうが安い。
しかし、「JavascriptやPHPやPerlやActionScriptが似ていてスイッチしにくい」
という意見もある。そういう場合でも、haxeのようなgenerativeな環境を使うことで
スイッチコストは落とせる。必要なものが無ければ自分で作ればよい。
組織全体の経営方針として、混乱の起きにくい、スイッチしやすい言語体系を
意図的に使うということも可能かもしれない。

6.同じプラットフォーム間でスイッチする。
WindowsやUNIXやMacや携帯電話など、異なるプラットフォーム間の
スイッチは非常にコストが高い。
だからかけもちをする場合はできるだけ同じプラットフォーム内でやるのがよい。
これもOSの依存性を排除するレイヤーを構築して、それを使えばよい。

7.タスク管理システムを統一しておく。
タスク管理のしくみがちがうと、いちいち異なる操作を思い出す必要がある。
その一端として、プロジェクトマネージャーを統一しておくのも良いだろう。
同じPMが管理する2個のプロジェクトをかけもちするほうが、
異なるPMが管理する2個のプロジェクトをかけもちするより簡単なはずだ。

8.プロジェクトの進行を調整する。
たとえば、最近では一つのプロジェクトに複数の言語やツールを使うことは多い。
RubyとC++とJavascriptを使うプロジェクトが2個あったとしたら、
(RubyとC++)→(JavascriptとRuby)→(C++とJavascript)
と推移させるより、
(RubyとRuby)→(JavascriptとJavascript)→(C++とC++)
と推移させるほうがスイッチコストが低い。
工程管理をうまくやることでこの調整ができる場合はあるだろう。

9.タスクスイッチの頻度とタイミングを最適化する。
2つのプロジェクトを1日で3回スイッチするのと、1回スイッチするのとでは、
コストが異なる。短期記憶は1日ぐらい維持できるから、1日に1回
スイッチするのが最小コストのはずだ。逆に、3日以上たつと忘れるから、
「月曜と火曜はプロジェクトAで、水曜〜金曜がプロジェクトB」とかは、
おそらく効率が悪い。だから「午前はプロジェクトA,午後はプロジェクトB」
がよいかもしれない。

10. IDEを使う。
統合開発環境は、開発サイクルを1周させるために必要な操作の思い出しが、
UNIXのようなばらばら開発環境よりも早い。
ばらばら開発環境→ばらばら開発環境
のコストよりは、
IDE→IDE
のほうが安いということだ。


まとめると、チーム全体でさまざまな要素に考えをめぐらし、
全体的に努力すれば、プログラマのスイッチコストを減らすことができ、
小さい組織の効率をもっと高めることができるだろう、ということだ。
逆にいうと、プログラマがいくら努力しても、
チームを越えて組織全体の協力がなければ、
タスクスイッチのコストは下げられないということだ。


余談:
プログラミングの作業が特別にかけもちしにくいのであって、
プログラミングの仕事以外の仕事とかけもちするのはそれほど重くないから、
かけもち度が低いエンジニアにPMや仕様書作成などの
仕事をかけもちしてもらうことで、幅広いスキルアップを見込めるかもしれない。

Posted by ringo : 2006年09月30日 10:09

トラックバック

このエントリーのトラックバックURL:
http://www.ce-lab.net/blog/mt-tb.cgi/387

言及リンクのないトラックバックは受け付けない設定にしています。
トラックバックスパムがあまりに多いための処置なので、ご了承ください。