コードを高速化する手段

私が知っている事でかなり基本的なことを紹介します。
中級以上向けの話ではないです。



●共通

・ データは局所的に置く

現在のCPUはキャッシュにヒットするかしないかが非常に大きな差になります。まとめて参照されるデータを構造体にすることは有る意味、効果的な対策です。逆に大域変数や静的変数を多用すると、遅くなる傾向があります。

・ メモリの確保回数は最小限にする

OSにメモリを要求する命令は特にコストが高いです。C++のメモリモデルは小さいオブジェクトを多量に確保するのには向いていないため、複数まとめて確保するメモリプールを行う関数を自作する必要があります。

・ 同期をとるデータを最小限にする

プロセス同期、スレッド同期、変数保護のうちどれが必要なのかしっかり見極めるべきです。特にプロセス同期はOS内部ハンドルを使用することになるため、極力さけるべきです。

・無限ループはまわさない

無限ループはCPUを100%消費し、本当に必要な事は殆どありません。WindowsでいうならSleep関数を利用したり、ポーリングしたり、待機関数を利用するなど適切な方法が他にあるはずです。

・標準関数を使う

memcpy相当の関数を自作して喜ぶ方がいたりしますが、最近のC++コンパイラに勝てるようなケースは稀です。何せ最適化されたコードに置き換えられる場合が殆どです。例えばx86では4バイト単位でコピーしていけば高速になるけど、同じ動作をするコードがコンパイラに組み込まれています。仮に相当な自信があって正当化できても、それは個人利用に留めるべきです。

・例外を有効活用する

C++の例外は低速ですし、なるべく動作させない努力はすべきでしょう。しかし、稀に起きるパターンすべてに対して条件分岐を張るより、例外を活用した方が速い場面や例外でないと防げない場面も存在します。例外を使わないプログラムが高速なのではなく、例外を誤用するプログラムが低速なのです。

●アルゴリズム

・アルゴリズムの種類を知る

コンテナに関係するアルゴリズムが5種類以上でてこなかった場合、貴方の知識は不足しています。
また、特性も知るべきです。たとえば、リスト構造は低速な部類に入ります。データ1つ1つがメモリに動的に割り当てられる場合、特に顕著です。複数まとめて確保すると多少改善されますが、データを参照するときにも低速になってしまう事も考慮しておくべきです。私もテキストエディタ等で利用したことがあるのですが、この場合は「ギャップバッファ」を用いるべきでした。

・計算量を知る

線形だ、Logだとかオーダーも大事です。それに加えて、必要とされるデータ量がいくつになるのかの見積もりも必要です。例えばMAXが数百のオブジェクトに対し、リストを避け配列を使うのは十分な合理性があります。C++のコンテナでいうならば、list, setやmapを使ってvectorに勝るようなデータの量は相当な数になることを知るべきです。

Leave a Reply

Be the First to Comment!

Notify of
avatar
wpDiscuz