ソフトウェアが遅い理由は、もうない
ソフトウェアが遅い理由は、もうない
我々が日々触れるソフトウェアの遅さは、ハードウェアの物理的限界なのか、それとも誰も手を入れずに積み上がった放置の結果なのか。そして最適化を実行するコストが崩れたいま、「それは高くつく」という業界の最後の言い訳さえ消えたのか。
導入
danluu(Dan Luu)が公開した記事のタイトルは、あからさまに挑発的である。「ソフトウェアが遅い理由は、もうない(There’s No Reason for Software to Be Slow Anymore)」。この40年でCPUは数千倍速くなり、メモリとストレージの帯域も、画面のリフレッシュレートも上がった。ところが実際に人が指先で感じる遅延——アプリが立ち上がる時間、ウェブページが描画される時間、キーを押して文字が画面に現れるまでの時間——は一向に縮まらず、領域によってはむしろ悪化してきた。ハードウェアが与えた恩恵は、どこへ漏れていったのか。
danluuの答えは以前から一貫している。性能は物理法則が定めた天井ではなく、努力すればかなりの部分を取り戻せる資源である。大半の遅いソフトウェアは「ここが限界」だから遅いのではなく、誰も取り戻そうとしなかったから遅い。今回の記事が新たに加えた角度は経済学だ。最適化という作業そのもののコストがAI支援コーディングによって急落し、これまで「性能チューニングは高くつく」と先送りしてきた判断の損益計算が丸ごとひっくり返る、というのである。本稿はその主張を三つの軸で検討する。何が遅いのか、なぜ遅いのか、そしてコストが崩れたあとに何が変わるのか。
取り戻せたはずの1秒 — 遅さの解剖
まず現象である。danluuの記事で最も具体的なデータは、彼自身のripgrep使用ログだ。著者は自分のマシンで実際に投げた検索クエリを計測しており、パターン長の中央値は55のUnicode文字、上位10パーセント(p90)が119文字であった。クエリ所要時間の分布はさらに劇的だ。上位1パーセント(p99)がほぼ1分、上位0.1パーセント(p999)がほぼ10分、最悪の単一クエリは実に2時間近くに達した。同時に、パターンの94パーセントはたった一度しか現れず、99パーセントが正規表現クエリで、99.9パーセントがASCIIのみの検索だった。つまりワークロードは驚くほど偏っているのに、道具は万人向けの汎用設計であるため、その偏りを活かせない。
著者はここに手を入れる。AIエージェントに自分のワークロードへ合わせた正規表現エンジン(FRE)の最適化をさせたところ、ネイティブAOTコンパイルだけで長いクエリでは2倍から4倍速くなり、代表性のあるホールドアウトのクエリ集合で約7パーセントの高速化が出た。自分のripgrep使用パターンに特化した版は、初回パスだけで標準のripgrepより2パーセント速く、なお改善中であった。注目すべきは、人がこの作業を始めるのに要した時間が約2分だという点だ。もう一つの事例として著者はボードゲームAzulのAIを挙げる。速度を二倍にするたびにおよそ100 Eloずつ強くなり、二番目に強いAIより開発時間が約100倍少なかったにもかかわらず、より良いマルチスレッド化と10〜20個の追加最適化を載せて圧倒的な首位を占めた。
ここまでは著者自身の実測である。ところが、こうした「取り戻せたはずの性能」の事例は、HNの議論ではもっと広範な日常ソフトウェアへ拡張される。HNの議論では、ある参加者が、1989年の原子力発電所の制御UIは画面を1秒で更新していたのに、今日のアプリはその応答性すら再現できない、という趣旨を投げかけた(年代や仕様は個人の回想であり正確性は確認されていない)。Apple Musicがハードウェアは十分強力なのに操作のたびにネットワーク要求を飛ばして苛立たしく遅い、という体験談、ある著名なデスクトップアプリが最上級のエンジニアを抱えながら数十ギガバイト規模のメモリリークを出した、という事例も飛び交った(数値はコメントの主張であり鵜呑みにはできない)。逆に、介入が効いたという事例もあった。HNの議論では、個人サイトのロード時間を4秒から750ミリ秒へ縮めたという報告、Redditのバックエンド応答は400ミリ秒なのにフロントエンドの描画に数秒かかる、という観察が出た。共通する含意は明白だ。遅さのかなりの部分は物理ではなく選択であり、取り戻せる場所に放置されていた、ということである。
「十分に速い」の経済学
ではなぜ放置されるのか。第一の理由は抽象化レイヤーの累積である。今日のありふれたウェブアプリは、ブラウザの上にフレームワーク、その上に状態管理、その上にコンポーネントライブラリ、その下にバンドラーとトランスパイラが幾重にも積まれた構造の上で動く。各レイヤーは開発速度を買い、実行速度を売る。HNの議論では、静的な地図一枚を描くために1メガバイトの地図ライブラリを引っ張ってくる類の無駄が指摘され、LLMにフレームワークを一切使わず素のNodeにExpress、EJS、PostgreSQL程度だけで書かせたら性能差が絶大だった、という体験談も出た。これに対し別の参加者は、それは結局エージェントにフレームワークをインライン化しデッドコードを除去せよと求めているだけで、十分に賢いコンパイラなら自動でやる仕事だと切り返した。レイヤーそのものが悪なのではなく、レイヤーのコストを誰も精算しない文化が問題だ、というわけである。
第二の理由はアーキテクチャだ。HNの議論の大きな軸の一つは「ネットワーク遅延が主犯か、バックエンドの非効率が主犯か」であった。一方は、米国外のユーザーが操作のたびに300ミリ秒ずつ乗るネットワークのブロッキングこそ体感的遅さの核心だと見た。他方は、それは表面にすぎず、開発者が「どうせネットワークが遅いから」という言い訳でバックエンドにさらに100ミリ秒ずつ無駄を載せるのだと反論した。不要な中間データ構造を作るような基礎の欠如こそ真の問題だ、という指摘である。データを物理的に離れたプロセッサ間で移す費用がローカル計算より数桁高いこと、それゆえベンチマーク上は5ミリ秒応答が容易に見えても、現実のサーバはリモートDBへ素朴に往復してその近くにも届かない、という観察も併せて出た。ローカルファースト(local-first)の設計でこの種の問題を丸ごと消せる、という処方にまで及んだ。
ここで過去の最適化文化と比べてみる必要がある。メモリがキロバイト単位でCPUサイクルが貴重だった時代、性能は選択ではなく制約であった。決まった予算の中に機能を押し込むには、手でアセンブリを磨き、データ構造をキャッシュラインに合わせ、不要なアロケーションを数える規律が強いられた。デモシーン(demoscene)が64キロバイトの中にリアルタイム3Dを詰め込んだのも同じ圧力の産物である。ハードウェアが潤沢になり、その制約が緩むと規律も一緒に緩んだ。問題は、規律が消えた場所を埋めたのが「もう気にしなくていい」という安堵であって、「余った余裕を応答性へ再投資しよう」という判断ではなかったことだ。最適化が必須から選択へ変わる瞬間、外部性の論理がその選択を支配し始める。HNの議論でも、1980年代のある時点でUIの速度が「受け入れられる」水準に達して以降、ハードウェアの恩恵は応答性の維持ではなく見た目と新機能へ流れていった、という趣旨の観察が出ていた。
第三の、そして最も根本的な理由は誘因構造である。性能は開発者ではなく利用者がコストを払う外部性だ。遅いアプリの代償はバッテリー、発熱、待ち時間という形で数百万の利用者に薄く散らばる一方、最適化のコストは特定チームの今四半期のスケジュールに集中する。HNの議論では、この非対称が組織構造として固まる、という観察がいくつも枝分かれした。チケット単位でしか回らない開発、部署間のサイロ、コスト帰属への執着が、合理的なリファクタリングを経済的に正当化不能にする、というのである。ある機能の使用文脈を一つのチームが理解できなければ、別のチームがそれを補正するコードを走らせることになり、そうして冗長が積み上がる。そしてどこかの時点で誰かが「これで十分速い」と宣言してしまえば、残ったハードウェアの恩恵は応答性の維持ではなくアニメーションと美しさ、新機能のほうへ再配分される。HNの議論では特に、macOSの一部のアニメーションが、すでに終わった作業を見せる前に人為的な遅延を強制してパワーユーザーを苦しめる、という不満が繰り返された。過去の最適化文化が消えたのではない。その文化が値を付けていた資源(利用者の1秒)が、組織の損益計算書から抜け落ちただけである。
最適化コストが崩れたあと
danluuの核心的な主張は、まさにこの損益計算書を書き直すことだ。最適化するかどうかは常に二つの値の比較であった。実装にかかる人時間(N人日)対、それで得られる性能の利得。これまで大半の最適化が「やらないほうがよい」と判定されたのは、利得がなかったからではなくNが大きすぎたからだ。著者はそのNが途方もない倍率で下がったと見る。人時間の基準では1,000倍から1,000,000倍、金額ベースの費用ではおよそ1,000倍(専門の性能エンジニアを使う場合に対して)。先のripgrepの事例で人の介入が2分だったという数字が、この主張の縮図である。Nがこれほど小さくなれば、かつて「利得はあるがその利得がNを超えない」とされた無数の最適化が、急にやってみる価値のある仕事になる。
ただし、この主張には確認しておくべき条件が付く。著者自身も、ベンチマークと実験設計の骨格は依然として人が立てねばならないと認めている。現在の最上位モデルでも、無人の最適化ループを回せるほどの実験設計能力は不足しているというのだ。HNの議論の懐疑論も同じ場所を突く。LLMは明らかに壊れたコードをプロファイリングして既知のパターンでリファクタリングするのは得意だが——あるJavaコードを350ミリ秒から60ミリ秒へ数時間で縮めた事例のように——すでによく最適化されたシステムに新しい改善を載せる段になると停滞する、というのである。「自分が何をしているか分からない人にはエージェントが助けになり、すでによく分かっている人には頭打ちになる」という要約が出た。実際のインタビューでも、人間の性能エンジニアは開いた問題での判断力は保つが、時間制限の付いた限定的な最適化課題ではもはや優位を保ちにくい、という観察があった。著者が引用したJamie Brandonは、モデルの解法に、自分は思いついたが着手できていなかった最適化が含まれ、「何週間も張り付かない限り試そうともしなかった無茶な手」まで含まれていた、という趣旨を述べた(原文の表現は意訳)。
実務者にとってこれが意味するものは何か。楽観シナリオでは、Marc Brookerの言うように「ワークロードの種類ではなく特定のワークロードに合わせた動的なカスタムソフトウェア」が標準になる。汎用の道具を各自の使用パターンへ仕立てる仕事が個人プロジェクトの水準でも経済性を持ち、企業は顧客ごとの最適化を大規模にパイロットできる。悲観シナリオでは、Nが下がった分だけ新機能と新しい抽象化も同じだけ安く積み上がり、取り戻した性能がすぐさま再び放置へ吸収される。現実シナリオはその間のどこかだ。介入点ははっきりしている。推測ではなくプロファイリングから始め、初回パスで出てくる明白な非効率(不要な往復、無駄なデータ構造)から潰せば、たいてい数十から数百倍の利得が出る、というのがHNの議論で繰り返された助言であった。魔法のような微視的チューニングを勧める記事がむしろ状況を悪化させる、という警告とともに。
結論
では遅いソフトウェアは限界なのか、放置なのか。二つの事例のデータと議論が指し示す答えは、圧倒的に後者である。我々が日々耐えている遅延の大半は、シリコンが定めた天井ではなく、誰も精算しなかった請求書だ。そしてdanluuの論旨が正しければ、その請求書を払わずに済ませてくれた最後の言い訳——「最適化は高くつく」——の有効期限が切れつつある。最適化のNが崩れた世界では、遅さはもはや技術的な不可避ではなく、明示的な選択になる。「十分に速い」という宣言は、いまや事実の記述ではなく、利用者の1秒を誰の損益計算書に載せるかという決定である。
ただし、コストが安くなったことと、実際に払われることは別だ。性能が外部性である限り、いくら安くなってもそのコストを自ら引き受ける誘因は依然として組織の中にない。だから本当の問いは、いまや技術ではなく意志へ移る。あなたのチームは次にハードウェアから得た恩恵を、利用者の応答性へ返すのか、それともまた一つのレイヤーへ飲み込むのか。取り戻せる1秒が目の前にあり、2分あれば始められるのに、それをやらない理由を、これから何と説明するのか。
出典: