高速化日記 (7) - Removing Code

年末にハカソンがあったので、自分は機能を削るとどれだけ起動が速くなるか実際にコードを消して調べることにした。一つ一つモードを消し、UI を外し・・・と一週間コードを消し続けた。しかし一ミリも速くならなかった。がっかり。

理由を考える。

まず前向きな理由がありうる: 余計なコードはクリティカルパスから取り除かれている。自分は余計なものをクリティカルパスからどかす作業を延々とやってきたわけだから、これはまあまあ的をいている。一方で、どうにも信じがたい。

最初の論点と少し関係がある仮説:起動などを遅くしているのは、モードや UI といった user facing feature のコードではなくフラグの定義やモニタリングのようなインフラっぽいコードである。そういうコードはどのみち消せないことがわかっているのでがんばって消すことをしなかったが、実際はまあまあクリティカルパスにあるのでほんとは消してみるべきだったのかもしれない。ただあちこちに断片的に埋め込まれてるので消すのが難しいのだよね。

このハカソンの少し前にフラグ取得の IPC がフラグの数だけ呼ばれまくっていたのを助っ人高速化隊のエースが発見し、それをバッチ化したら起動がぐっと速くなる出来事があった。これはインフラ税の存在を裏付けている。

自分が消していない部分に遅さがあるという意味だと、画像処理や C++ の中にある余計なコードがクリティカルパスにある可能性もある。画像処理パイプラインの「機能」は、わかる人には消せるのかもしれないが自分にはむずかしい。そしてこれらの「機能」は年々複雑化が進み、遅くなっている。

もうちょっと red herring な説: 一旦コードに持ち込まれた複雑さは、単純にコードを消すだけではキャンセルすることができない。たとえば新しい機能のためにリファクタリングして間接化や抽象化を足したとする。コードを消すと抽象化の裏にある実装は消えるが、抽象や間接化そのものが消えるわけではない。コードを消したら、そのあとよくコードを読み直して余計な抽象化を見つけ出し、それをベタなコードになおしてはじめてオーバーヘッドを取り除くことができる。かもしれない。自分は心の奥底でこの説を信じている一方、検証するのは難しいいイチャモンという面もあるのであまり強く主張する気にもなれない。


いずれにせよ「コードがでかくなると遅くなる」というのは必ずしも絶対的な真実ではないし、逆が真とも限らない。たとえばデスクトップ環境に巨大なアプリをインストールしたところで(そのアプリを起動しなければ)対して遅くはならない。一方でサーバに daemon の類をインストールすれば少しは遅くなるだろう。Android のアプリはその間くらい。単一プログラム内の余計なコードがデスクトップアプリのインストールとサーバの daemon のどちらに近いかは、ケースバイケース。というわけで「コードがでかい = 遅い」は経験則のひとつに留め、鵜呑みするのはやめましょう、という話。

そしてコードを消す話をするといつもこれを思い出してしまう人生の呪い。