怠惰はエンジニアの美徳 #4

あれは10年ぐらい前のこと

エンジニアとして駆け出しだった自分は寝ても覚めても腕を磨くことを考えていた時期で、特に「設計力」というものを身に着けたくて、目に映るものを片っ端から頭のなかで設計してみるという修行を自分に課していた。たとえば自動改札機を通り抜けたなら、「この切符のIDはこうやって割り振って売上のデータはこの形式で保存して・・」などといった具合である。

そんなとある日、山手線でつり革を持ちながら壁に貼ってあったキャンペーン広告をなんとなく眺め見た瞬間、凍りつくような驚愕を覚えた。

それはだいたいこのようなキャンペーン広告だった


「1分に1人当たるプレゼントキャンペーン実施中!」
〜キャンペーン期間中に、XYZカードに加盟しているデパートやファミレスなど、全国合計10万店舗のどこかのレジでXYZカードを使ってお買い物をしたら、1分に1人のペースで購入したお客様にプレゼントが当たるキャンペーンを実施しています!〜

・・・これは大変なことになった。こんなシステムを作れるだろうか?何から手を付けよう?

全国に10万店舗あるレジに、1分に1回どこかのレジで当選者がでるように仕組みを作らないといけない。

1店舗に平均して10個レジがあるとしたら、10万店で100万個のレジになる。100万個のレジにプログラムを仕込むのは相当な作業になる。そしてデパートやコンビニ、ファミレスまで多種多様な会社があつまっているので、レジのOSも様々なはずで、それぞれについてプログラムを開発しないといけない。

もしそれが出来たとしても、100万個のレジから中央サーバに1分に1回問い合わせて、「次の1分で自分のレジであたりを出すか?」を確認することになるとしたら、平均して1秒あたり1.6万のアクセスが中央サーバに集中することになる。10年前の当時、そのようなサーバを構成するには莫大なコストがかかるはずだった。

一体このプロジェクトには何億の開発運用コストがかかっているのだろうか?

目の前が真っ暗になりかけたその時、一瞬のひらめきが脳内を浮かび、「あ、なんだこれでいいのか!」という数学の問題を説いた時のような爽快感に包まれることになった。

いったいどのように解決したのだろうか?

僕はその時、過激なサボり方を見つけたのであった。
(そしておそらく現実的にもこのような方法で運用されていたに違いない!)

それはこのような解決策である。

1. 100万台のレジがある
2. 平均して1分間に1人がレジを通過すると仮定する
3. レジは営業時間中、休みなく動いていると仮定する
4. そうすると平均して1分に100万人がレジを通過する
5. 1分に1人当選させるためには、1/100万回の確率で当選すればよい
6. 1/100万の確率で当選者を出すようにすべてのレジに設定する
7. この方法で運用すると、結果的に”だいたい”1分に1人プレゼントが当選する

いかがだろうか?

2,3の仮定値は実測値に応じて設定すればいい。
6の実施方法はレジのソフトウェアで設定してもらってもいいし、それが難しければ「この日にこの店舗のこのレジで何時何分に当選を出す」というアナログな決め方によって実現することもできる。それぞれの企業毎に最適な方法で実施してもらえばいい。(レジのソフトウェアを更新することになっても、通信なども発生しないためそこまで大きな開発時間はかからないだろう)

まじめに実現する方式と怠惰な方法を並べてみてみよう

まじめ方式:
全国のレジから中央サーバに定期的に通信を行い、抽選により当選するレジを決定する

怠惰な方式:
通信はせず、期間中は適度な確率で当選させるよう各レジに設定しておく

何らかの事情で絶対確実に1分間に1人を当選させたいのであればこの方式は使えないが、そこまで厳格ではない場合はこのように適度な”サボり方”をすることで、開発コストはおそらく数百分の1にまで節約できるのである。

今回の例はいささか極端で分かりやすい例ではあるが、設計段階の方針決定がいかに重要かを教えてくれる。勤勉な国民性の日本社会ではそのまま真面目に実装するがゆえに開発コストが跳ね上がってしまうことは多々あるのではないだろうか。あるいは国家予算を使って開発するようなソフトウェアは、開発する会社があえて高い見積もりを出すために、過剰に真面目な設計を持ち出してくることで、莫大な予算を無駄に消費してしまう現象も起きがちである。ソフトウェアはコストをかけようと思えばいくらでも多くかけられるのである。そしてまた優秀なプログラマは普通のプログラマの数十倍のパフォーマンスを発揮するといった研究結果(とそして実感)も存在するが、このような「設計思想での思い切り」のセンスも関係しているだろう。

Perlというプログラム言語を開発した偉大なエンジニアであるラリー・ウォール氏によれば、エンジニアの三大美徳は「怠惰」「短期」「傲慢」であるらしい。「怠惰」ゆえにすべてを自動化しようとするし、最低限のコストで目的を果たす方法を考えている。優秀なエンジニアであるほど、楽するために努力しているのである。

エンジニアの服が毎日同じであっても、いつも同じカップ麺を食べていたとしも、「面倒くさい」が口癖であっても、髪に謎の糸が付いてても、許してあげよう。

怠惰はエンジニアの美徳なのだから。