マイナス2,000行のコード
(folklore.org)- 1982年初頭、Lisaソフトウェアチームは6か月以内に出荷しなければならないプレッシャーの中、エンジニアごとの週間のコード行数で進捗を測ろうとした
- Bill Atkinsonは、行数は生産性を正しく示せず、小さく高速なプログラムを作るという目標にも反すると考えた
- QuickDrawの領域計算エンジンを、より単純で汎用的なアルゴリズムで書き直したところ、領域演算はほぼ6倍高速化し、コードは約2,000行減少した
- 最初の管理フォームで、その週に書いたコード行数を尋ねる項目に、Billは
-2000と記入し、測定方法の欠陥をそのまま示した - 数週間後、管理者たちはBillにそのフォームの提出を求めなくなり、この逸話はコード行数ベースの管理が実際の改善を見逃し得ることを示している
Lisaチームのコード行数測定
- 1982年初頭、Lisaソフトウェアチームは今後6か月以内にソフトウェアを出荷するため、作業ペースを上げようとしていた
- 一部の管理者は、各エンジニアが毎週書いたコード行数で進捗を追跡しようとした
- エンジニアたちは毎週金曜日に提出するフォームを受け取り、その中にはその週に書いたコード行数を記入する項目があった
Bill Atkinsonの-2000
- QuickDrawの作者であり、主要なユーザーインターフェイス設計者でもあるBill Atkinsonは、Lisaの実装で重要な役割を担っていた
- Billは、コード行数という指標は生産性を正しく測れないと考えていた
- 優れたソフトウェアの目標は、可能な限り小さく高速なプログラムを書くことだと考えていた
- 行数を増やす指標は、粗雑で肥大化し、壊れたコードを書くよう促しかねない
- 当時、彼はQuickDrawの領域計算エンジンを最適化していた
- より単純で汎用的なアルゴリズムで領域エンジンを完全に書き直した
- 調整後、領域演算はほぼ6倍高速化した
- 同時にコードは約2,000行減少した
- 最初の管理フォームに記入する際、コード行数の項目をしばらく見た後、
-2000と書いた - 管理者たちがどう反応したかは定かではないが、数週間後からBillにはフォーム提出を求めなくなった
1件のコメント
Hacker News の意見
Microsoft と IBM のコード行数をめぐる衝突の事例を思い出す
Bob Cringely の Accidental Empires を基にした PBS のテレビシリーズで、Steve Ballmer が IBM と OS/2 を共同開発していた経験を語る場面がある
Microsoft は小さな会社のように仕事を終わらせる姿勢だった一方、IBM は社内指標、とりわけプログラマーの生産性を KLoC(千行単位のコード行数)で測ることに集中していたという
Ballmer は「彼らが気にしていたのは KLoC、KLoC、そして KLoC だけだった」と述べ、IBM はコードの良し悪しより量の多さを見ていたようだ
https://ubiquity.acm.org/article.cfm?id=1022357
事情を知る人たちは、その「祝賀」を葬式のように受け止めていた
コード行数を生産性指標として数えるのは本当に愚かだ
20年前から解けなかったバグをコード1行で直したことがあり、3年前からのバグは
order byひとつで解決した覚えがある。コード1行の影響をどうやって測れるのか。経験上、悪いプログラマーのほうがはるかに多くのコードを書くMicrosoft の開発者が3万3千文字の IBM のコードを書き直して220文字に縮めたという話[1]も忘れられない。その結果、Microsoft の作業量は「マイナス」になり、戦争になったという
[1] https://archive.org/details/bigbluesunmaking00carr/page/4/mode/2up 101ページ
最近の例では、「影響力」、つまり新製品のリリースを昇進基準にしている会社がある。そうすると、誰も保守しない失敗した製品が山ほど生まれやすい
偉大なコンピューター科学者やエンジニアの中には驚くほど多くのコードを生み出した人がいて、それが何らかの形で影響力に直接つながると信じている。問題は、コード行数が成果測定の指標になった瞬間だ
そのときは Goodhart の法則、「測定値が目標になった瞬間、それは良い測定値ではなくなる」が当てはまる
生産性指標の観点ではコードを資産に分類するが、実態により近い見方は、機能こそが資産でありコード自体は負債だというものだ
この話題はよく上がる。過去の議論は次の通り
https://news.ycombinator.com/item?id=33483165 (2022)
https://news.ycombinator.com/item?id=26387179 (2021)
https://news.ycombinator.com/item?id=10734815 (2015)
https://news.ycombinator.com/item?id=7516671 (2014)
https://news.ycombinator.com/item?id=4040082 (2012)
https://news.ycombinator.com/item?id=1114223 (2010)
https://news.ycombinator.com/item?id=1545452 (2010)
キャリアの初期に引き継いだ1万行超の C プログラムを500行未満に最適化したことがある。Sybase データベースに SQL 呼び出しを行う C プログラムだった
すごい洞察があったわけではなく、前任者は関数の使い方や、SQL クエリに可変データを入れるためのパラメーターの使い方を知らなかった可能性がある、という単純な仮定からだった。実際、同じ SQL 文を値をいくつか変えただけで毎回インラインに書いていた
SQL 呼び出しのコードを関数呼び出しに書き直し、バインド変数を関数のパラメーターとして渡すようにした。繰り返されていたインラインコードは、配列から変化するバインド値を受け取り、ループ内で関数を呼び出す方式に置き換えられた
最大の影響は、ときに「X はどう処理するのか?」のような単純な質問を投げかけ、何かをそもそも作らせないことから生まれる
その何かが正しく動く機会すらなかったのなら、作ろうとする全体のコストを節約したことになる
こういうことは数値指標では測定不可能なだけでなく、敵を作ることにもなる。それでもあえてそうする人たちには拍手を送りたい
プログラミングを高速タイピングのようなものだと考える人たちは、LLM と興味深い類似性を示す。うまく書かれていないコードを全部書いては消し、また書いては消す、という具合だ
部署に入ってくる情報リクエストの半分ほどは、いつも「非常に重要で、今すぐ必要で、大金を稼ぐか節約できる」という類いだったが、明白な答えは「すでに持っている情報で計算してください。計算機とスプレッドシートがあるでしょう。鉛筆を差し上げましょうか?」だった
システムに X を処理させるより、避けるほうがよい。1、2回使われるかどうかの特殊ケースがシステムを肥大化させ、誰もそうした特殊ケースやプログラムが存在するのか、実際に何をするのかを知らない。文書化がよくできていても、何が可能かを学ぶことに時間を使わない。だからそうした特殊機能の多くは、実際には時間の無駄になる
対応する思考実験として、逆の状況を考えることもできる。管理者がこの記事を読んで、単純に削除したコード行数で測ることにしたら、良くなるのか、悪くなるのか?
この種の測定は、全体として堅実なコードレビュー慣行がない限り、ほとんど役に立たない。ここの人たちが信じたがることとは違い、そうした慣行は珍しい。しかし良いレビューがあるなら、低パフォーマンスや指標の操作も捕捉できるので、そもそもこのような指標を導入する理由は少なくなる
たとえば、ソフトウェアエンジニアと難解なコードテキストをすべてなくし、プロダクトマネージャーが特殊な図やフローチャートを描いて「ローコード」や「ノーコード」の成果物を作る形に置き換えよう、という古くからの発想がある
追加行と削除行を別々に数え、
+50,-150のパッチは 200 ΔSLOC として計算するこれは生産性を測る良い尺度ではなく、特に単独ではなおさらそうだ。それでも変更量を大まかに計算するナプキン計算の指標としては妥当だ。ΔSLOC が高い開発者が、1〜2週間まったく ΔSLOC のない同僚より生産的かどうかは、その同僚が何をしているかによるが、測定期間中に前者がコードベースをより多く変更していることは確かだ
製品が「完成」しているなら、同じか、より良くなるかもしれない。そうでなければ、負のコード行数変更はデプロイまで到達しないだろうから
しかしほとんどの製品は進化し続ける。だからこそ私たちは同じプロジェクトに何年も留まることができるのであり、削除だけの貢献は結局何も付け加えないことになる
本当の話は、プロジェクトを始める時点では、正確にどこへ向かうのか分からない場合があるということだ
進めるうちに問題と望む答えをはるかによく理解するようになり、そうすると大きな塊を取り除いて、より小さくより良いものに置き換えられる
そしてこの人たちは
-2000行のコード、しかもアセンブリコードまで含めて、すべてを 64KB ROM の中に収めなければならなかったことも忘れてはいけない。より小さくせよという圧力は非常に強かった実際に ROM にあったのか、起動フロッピーにあったのかも定かではない。付け加えると、Wikipedia によれば Lisa の ROM は 16KB だったという
[1] https://computerhistory.org/blog/the-lisa-apples-most-influential-failure/
[2] https://computerhistory.org/blog/macpaint-and-quickdraw-source-code/
Atkinson Ditherで有名な Bill Atkinson。 https://beyondloom.com/blog/dither.html
その過程で、ユーザーインターフェースが動作する新しい方式と、それを実現するためのソフトウェアの書き方を絶えず発明しなければならなかった。彼は「Macのハードウェア上で高速に実行できる」ことと「優れたユーザー体験を提供する」ことを同時に最適化し、そのシナジーが昔の白黒Macの美学全般に彼の痕跡を残した。あのディザリングスタイルも、アルゴリズム的な天才性と美的感覚が組み合わさった、もう一つの例だ。
こうした感覚は、「marching ants」の選択枠(https://en.wikipedia.org/wiki/Marching_ants)のようなものにも表れている。クラシックMac UIの多くのフィードバックがピクセル反転で表現されていたのも同様だ。テキスト選択、メニューのハイライト、マウスボタンを押している間のボタンの見え方、ウィンドウをドラッグするときの境界線などがそれで、XORモードで上から描画するのは、こうした効果を作るのに非常に適した方法だった。
QuickDrawでこうした道具を組み合わせたやり方は、Steve Jobsとの有名な角丸長方形に関する会話(https://www.folklore.org/Round_Rects_Are_Everywhere.html)が、実際にQuickDrawで長方形と同じくらい簡単に角丸長方形を描けるようになる結果につながり、OSのいたるところに角丸長方形が現れるようにした。
Mac UIの成功は、単に見た目が良かったからではなかった。大きな部分は、Bill Atkinsonが見栄えの良いものを簡単に作れる、賢く小さな道具一式を作ったからだ。
Susan Kareの素晴らしいアイコン群も、Billが32x32ピクセルのマスクビットマップをUIに簡単に入れ、クリック時に反転できる道具を作っていなかったら、あれほど愛情をもって記憶されることはなかっただろう。
教訓は、Einsteinほど賢くても結局は従業員であり、従業員としてやるべきことをやらなければならないということだ。
人々が書いたコード行数を語るとき、なぜいつも「追加した行 - 削除した行」で計算するのか理解できなかった。
私が10kmランニングをして出発点に戻ってきたからといって、0km走ったことにはならない。
例えば
if cond { ... return; } ...という形をif cond { ... return; } else { .... }に変えるような場合だ。とはいえ、その説明ですべてを網羅できるわけではない。