C/C++のプログラム高速化
C言語、C++言語のプログラム高速化について書いていこうかと思います。
C実践プログラミング、C++実践プログラミングの本(共に、O’REILLY出版)を読んで、その中に乗っていたことを主に書いていきます。
関数をマクロ化
処理を関数として書くよりも、1~2行程度の処理であれば、マクロとして書いたほうが速く実行できます。
例
int sqr(int x) { return (x*x); }とするよりも、
#define sqr(x) ((x)*(x))としたほうが速くなる。
このとき、#define sqr(x) (x*x)などとしないように注意する。
配列の初期化はポインタを利用
二次元配列mat[5][9]を初期化する際には、mat[0][0]のポインタから、mat[4][8]のポインタまで、ポインタを1ずつずらしながら初期化していきましょう。
ライブラリ関数を使う
もし、実行したい処理を行うライブラリ関数が存在すれば、迷わずそのライブラリ関数を用いる。頻繁に用いられるライブラリ関数はアセンブリ言語で記述されていることが多く、プロセッサに依存した手法を利用し、C/C++で書くようよりも高速な処理が可能になる。
読み書きするファイルをバイナリ化
読み書きするファイルがASCIIで書かれているよりも、バイナリとして書かれているほうが処理が早く済むようです。詳しくは、scanfが非常に時間のかかる処理だから、だそうです。
複雑なループを内側へ
ループが何重にもネストする場合、もっとも内側のループは、もっとも複雑な処理を書くようにしましょう。
浮動小数点演算をできるだけ使わないように
できるだけ、浮動小数点演算を行わないようにしましょう。少しの工夫で整数演算に変えれる場合は、整数演算にしたほうが3倍~20倍にまで速くなります。
2の累乗
コンピュータの内部は2進数を使っているので、10の累乗を使うよりも2の累乗を使うようにしましょう。
要素の交換はポインタの付け替えで
構造体など、多くのデータを持ったデータを入れ替えたりするには、データを入れ替えるのではなく、ポインタを入れ替えるようにしましょう。
register修飾子
通常の変数宣言int x;などは、メインメモリ中に格納されます。が、頻繁にアクセスされる変数は、アクセスに比較的時間のかかるメインメモリよりも、高速なレジスタに格納したほうが早くなるそうです。レジスタに格納するために、変数宣言をregister int x;のようにします。
通常のPCの場合、レジスタは2個程度、大多数のUNIXシステムでは11個前後、スーパーコンピュータでは128個くらいのレジスタを備えているようです。使用できるレジスタの数よりも多くのレジスタ変数を宣言しても良く、多すぎる分はメインメモリに格納されるようです。
実際には、register修飾子はあまり使われていないようです。
その他(アルゴリズム・データ構造)
上で紹介した高速化手法よりも重要なのが、使用するアルゴリズム、データ構造の吟味。これらをしっかり考えたほうが、プログラムはより高速になります。
関連記事
- PCが遅くなったら「Glary Utilities」
- [Linux] gcc, g++ によるC/C++のコンパイル・オプション
- [C++] Dimensionクラス
- [PHP]エラーログ記録関数
- パソコンのキーバインドを変更する方法
[PR]
トラックバック
http://yamablo.com/2009/01/21-173456.php/trackback

