計算量の見積りは「最適化するするため」だけではなくて「複雑な最適化をしないで済むため」にも大事

とくにサーバーサイドのソフトウェアエンジニアリングにとって、計算量の見積りをするのは大切だ。というと、「うん、そうだよね、最適化って大事だよね」という話になりそうだけれど、今回書くのはそういうことではなくて、むしろ「最適化をしないで済むために計算量の見積りが大切」という話。

たとえば、計算量の見積をせずに「なんとなくこのあたりが重くなりそうだからキャッシュ入れておこうか」「なんとなくこのあたりが重くなりそうだから工夫したアルゴリズムにしておこうか」としたとき、わたしたちは「状態を新たに導入したことにより、状態の同期を考えなければならないコスト」や「複雑なアルゴリズムをメンテし続けるコスト」を引き受けている。しかし、このときに「ここの計算量はたがだかO(log N) であるな」とか「たかだか線形であるな」とわかっていれば、「たかだがO(log N)なので、まあキャッシュせずに毎回計算でええやろ」とか「たかだか線形なので、(ページネーションなどで)Nの数にcap持たせる仕様にしても問題ないならそれでええやろ」としてメンテナンスのコストを引き受けずに済む。あるいは、「ここの計算量がO(N2) になってしまうなあ」とわかっているときに「じゃあもっといいテーブル設計できないかな」と検討しなおすことで安易にキャッシュしたりせずにすむかもしれない。

わたしはいままで結構、「創意工夫」の結果複雑な状態管理や複雑なアルゴリズムになってしまっているシステムを見たり作ってしまったことがあるが、そのうちの結構な数が、「そもそも計算量ちゃんと見積もったら全然問題ないところを創意工夫している結果生まれた複雑さ」だったりした。

なのでまあ、計算量を見積もるというのは「パフォーマンスに困った時にやること」じゃなくて、そもそもコード書く時、テーブル設計するときに計算量を見積もって、いらん創意工夫をしないためにもやるといいんじゃないかな、と思ったという話でした