見出し画像

ソフトウェアの高速化に取り組む前に行っておきたい作業3選

30年以上プログラミングをしてきたムンペイです。

プログラム高速化が好きです。プログラムを高速化するとはつまりプログラムの実行が遅い部分を修正して改善するということですが、プログラム修正に先立ってぜひ行っておきたい作業を3つ選んでみました。


1. プログラムの目的を確認する

まず、このプログラムが何をするものかを、確認しておきます。
プログラム修正の工程でどの程度まで変更してよいかを見極めるための材料となります。

この時、プログラム単体から得られる情報よりももっと広く、このプログラムが組み込まれた一連のワークフローの内容やその目的まで把握することができると、高速化の主眼となるポイントをより精度よく理解できますし、修正の選択肢も増えます。
例えば、ファイル読み込み処理が非常に遅い場合は、データ交換用のファイル形式を読み書きに適した形に変更するという方法も考えられます。また、対象プログラムの高速化が難しい場合でも、このプログラムの前後の別の処理と並行して実行できるならば、ワークフロー全体としては高速化できる可能性もあります。

一方、プログラム単体だけから得られる情報だけで高速化する場合は、局所性の改善(記憶階層に対する改善)や、効率の良い命令への置換など、選択肢はコンピュータアーキテクチャに基づくアプローチに限られてきます。

2. テストを作る

次に、テストを用意します。
高速化では、より良いアルゴリズムや実装方法が見つかった場合、プログラムを大幅に変更していくこともあります。この時、テスト(レグレッションテスト)を用意しておいて、変更によってバグが入ってしまっていないかを頻繁に確認しながら作業を進められれば大変安心ですし、作業速度も上がります。

テストは、変更によってバグが生じていないか判断できるように、十分なバリエーションを持つ必要があります。また、変更とテストのサイクルを頻繁に実行していきたいので、手作業ではなく自動化されたテストが強く推奨されます。このあたりはユニットテスト、テスト自動化、テスト駆動開発、などと同じ観点となりますので、そちらの情報も参照ください。

なお、高速化の種類によっては、処理結果に変わることを許容するケースがあります。たとえば、JPEGエンコーダ(圧縮プログラム)を高速化した場合、圧縮後のデータは微妙に数値が変わることはあり得ます。しかし、これをどのように受け止めるかは変更目的(要件)によります。圧縮後のデータが1ビットたりとも変化してはいけないという要件ならばこの高速化は不合格です。
しかし「画質が同程度ならば問題ない」という要件ならば、データが変わる高速化は受け入れられますが、テストも圧縮後のデータの品質を評価する指標に基づいたものでなければいけません。例えば圧縮を解いたあとのデータ(伸長データ)が、圧縮前のデータに対して、差分の最大値が±4に収まっていること、といった感じです。
一般的には、データ変更を許容する方がより大きなプログラム変更の余地が生まれ、高速化の可能性も高まるでしょう。

3. 実行時間計測の仕組みを作る

「計測できないものは制御できない」と、"Controlling Software Projects" でトム・デマルコは言ったそうです。デマルコ自身は後年のインタビューでソフトウェア開発において真に集中すべきは別の点であると述べたのだそうですが、こと高速化に関してはこの言葉は依然として有効です。

計測する目的は二つあります。一つは、プログラムのどの部分を高速化すれば最も効果が高いかを見極めることと、もう一つは高速化の成果を測ることです。

これらを達成するためには、プログラム全体だけでなく、部分に分けて測る必要があります。「部分」をどの程度まで細分化するかはなかなか悩ましいところですが、ある程度まとまった単位がよいでしょう。経験的には10、多くても30程度です。それ以上に分けたくなったとしたら、細かすぎるか、プログラムの責務が複雑すぎるかのどちらかでしょう。

実行時間の計測は、高速化作業の中で何度も繰り返し実施したいため、手作業ではなく、システマティックに計測できる仕組みを作っておくことが強く推奨されます。
システマティックな計測の仕組みとしては、プログラム中に実行時間を計測する機能を作りこんでしまうのが「部分」の粒度を精密にコントロールできるので最もおすすめです。他に、プロファイラと呼ばれるツールにより関数単位の実行時間・呼び出し回数などを計測する方法もあり、こちらは修正作業で使っていくことになります。

逸る気持ちを抑えて・・

高速化をやろうという人は、きっとプログラミングが大好きな人でしょう。早く修正に取り掛かりたいという気持ちが抑えきれないかもしれません。しかし、そこをぐっと我慢して、目的の確認、テストの用意、計測の仕組化、を行っておくことで、その後の作業がずっと効率的に行えます。

準備が整ったら、いよいよプログラムの修正です。高速なプログラムを書くためのコツ3選で書いた基本的な指針に従い、具体的な検討を行っていくわけですが、それはまた別の機会に。

これにて御免!

(見出しにはUnsplashGilberto Olimpioが撮影した写真を使わせていただきました)


この記事が気に入ったらサポートをしてみませんか?