2006-04-14

近況

そんなわけで Shibuya.js Technical Talk #1 に行ってきた. 全体に今時の若者(=ウェブの人)らしいノリで楽しめた. 開催者の方はありがとうございました. 次回にも期待しております. (実費+aくらいは集めていいと思いました.)

講演の中で特に印象的だったのは 最速インターフェイス研究会の mala さん. 他の講演者がサーバサイドの開発者というかんじなのとは対照的に, この人は一貫してクライアントサイドの開発者だった. 講演で示された作業様式がクライアントサイド開発を徹底している. サーバサイドのプログラマがあれこれ理由をつけて逃げがちな問題を 解決しようとする姿勢がいい. たとえば 萌ディタ を使う理由も (半分くらいは単なる趣味なんだろうけれども) それらしさがある. HTML/CSS/JS 混在環境での syntax hilighting や, OLE によるブラウザとの連携. 典型的なプログラマなら諦めてうんざりしながら作業をするところだろう. WEBrick proxy を使ってコンテンツを差し替えながら開発をするという話も同様. サーバのコードだけで暮らしている人間には考えもつかない 優れたアイデアの数々に心の中で拍手喝采した.

その後少しは社交をしておこうと思うもまったく知り合いがおらず bootstrap に失敗し, ややさびしい感じで退散. こんなさびしい思いをするのは Shibuya と js に対する愛が足りないせいかもしれないと, 渋谷 Book1st で サイの本 を買って帰った.

プログラミングの最後の一里

開発作業のターンアラウンドを改善するのは プログラミングの生産性を高める上で重要な課題だ. そのためには作業を自動化しろとよくいう. いちいち GUI を操作するのは時間の無駄だと. 自動テストや各種スクリプト環境はそうした要求に応えるべく発展してきた. "怠惰さ" を美徳とする一部プログラマの信仰も動機づけに寄与している.

ただ人手による繰り返し作業のボトルネックが解消すると, 今度は計算機や環境の性能がボトルネックになる. 要するに待ち時間がうまれる. コンパイルとリンク, アプリケーション・サーバやエミュレータの再起動, ファイルの転送, 自動テストの実行. 自動化されているとはいえ, これらの作業は時間がかかる. 数十秒から数分, 時には数十分. その間, プログラマは指をくわえて待つしかない. 自動化の限界はここにある. 私はこれを プログラミングの last one mile 問題と呼んでいる. (...というのは嘘. いま思いついた.)

最後の一里を前に力尽きるプログラマは多い. ぼんやりと画面を眺め, コーヒーを飲み, メールを確認し, ウェブをぶらつく. そしてとうの昔に終わったビルドとテストに気づき, 必要以上に時間を使ってしまったとがっかりする. 残業はつづく.

待ち時間の解消に怠惰さは役立たない. 一部のプログラマはこの時間をどう有効活用しようかと考えだす. その方向は袋小路だと私は思う. 人間はコンテクストスイッチのコストが高く, 細切れの時間を活用するのは難しい. だからその時間を減らす方法を考えた方が道は明るい. 一方で, 解決が難しい問題なのもわかる. 実際のところ私もぼうっと画面を眺めている時間は長い. だからターンアラウンドを短縮する ma.la さんのアイデアには感銘をうけた. 最後の一里に歩みを進めるプログラマたちは尊敬に値する.

最後の一里の最初の一歩

最後の一里を進む待ち時間の短縮は高速化の一種だと考えることができる. 開発対象の高速化ではなく, 自分の作業をチューンする作業. やってみると案外手応えがあって楽しい. 作業を自動化しているのに効率があがらないと感じていたら, こうした高速化を試してみるといいかもしれない.

思いつく範囲のアイデアを以下にいくつか並べておく. なお, 最後の一里が問題になるような状況では以下に示す汎用的なやりかたより システム固有のツールチェインや設定を見直す方が効くことは多い. プロジェクトの初期になんとなく決めた構成が, 時間が経つにつれて足をひっぱるケースがあるからだ. (遅いバッチファイル, 適当に書いた依存関係の解決, 冗長なリソース同期, 無意味な再起動など.)

また他の同僚の作業を覗いていると IDE の細かい設定や 見たこともないツールやショートカットやスクリプトを使って 抜け道を作っていることがある. そういうのを観察して真似するのもいい.

速いハードウェアを使う

当たり前ではあるけれど, 速い CPU, 大量のメモリ, 多重化されたディスクはとても効く. 特にディスク. 会社で RAID のディスクを積んだ PC を支給された時, ビルドの速さに驚いた. 頑張って駄々をこねてでも買ってもらう価値があると思う. (いつか RAM ディスクにソースをチェックアウト, ビルドしてみたい...)

組込み分野では, オブジェクトファイルの転送に使う ケーブルやソフトウェアに転送速度の速いものを使う. 大半は選択の余地が無いけれど, 代替品のあるシステムもたまにある. ベンダに問いあわせてみるといい.

軽いアプリケーション・サーバ, エミュレータを使う

アプリケーション・サーバの起動時間は実装によって差がある. だから開発中は実際に使うもののかわりに起動の速いサーバを併用することができる. たとえば Eclipse の plugin から Tomcat を毎回起動するより, 自分で書いたコードから Jetty を起動する方がだいぶ速い. だからローカルでの自動テストでは Jetty を使うとターンアラウンドを 改善できることがある. データベースも MySQL を使うより sqlite や HSQL のような インプロセス式のものを使う方が速い場合がある.

ケータイのアプリケーションなら, IDE からエミュレータを起動するより 可能ならプログラムやコマンドラインから呼びだす方が速い. またデバッガの上で起動するより, デバッガをアタッチせず直接起動する方がずっと速い.

自動テストのスコープを最小化する

自動テストで重いフレームワークの起動やファイルの入出力があると時間がかかる. フレームワークを使わず, オンメモリで解決できるようテストを修正する. いわゆる "単体テスト" 主体で開発できるのが最も望ましい. Working Effectively with Legacy Code でも, 単体テストは I/O や外部の環境を使わず, 各ケースが 0.1 秒以内に収まるよう指示している.

ヘッダファイルの依存関係を最小化する

無駄なヘッダファイルを include しているとコンパイルに時間がかかる. そういう意味で STL や boost は悲惨だ. モジュールを分割し, モジュール内部のヘッダを 他のモジュールから隠すとビルド時間を縮小できる. pimpl イディオムはそのための方法のひとつ. 大規模 C++ ソフトウェアデザイン はそうした話題に詳しい.

インクリメンタルリンクを有効にする

Visual C++ はインクリメンタル・リンクをサポートしている. これは標準で有効になっているのだが, 歴史の長いプロジェクトだと何かの都合で無効にされたままになっていることがある. 確認してみるといい. プリコンパイル・ヘッダも同様.

GNU は ld のリンクが遅いのをなんとかしてほしい... バージョンによってだいぶ速度が違うという話もある.

この路線の最先端は分散ビルドだろう. 私は試したことがない.

キャッシュを無効化する

JSP や Tapestry などのフレームワークは前処理の結果をキャッシュするため, 変更に応じてフレームワークを再起動する必要がある. 設定でキャッシングを無効化するとフレームワークの再起動が必要なくなり, ターンアラウンドを改善できる. (最近の JSP は大抵自動的にキャッシュを更新してくれる気がする.)

...

こう書き出してみると大した案はないね. 工夫が足りてないのかも. ドメイン依存のものでもいいので妙案のある人は教えてください.