C++コード最適化(1)


C++が良いのかJAVAが良いのか、どの効率が高いのかなど、フォーラムでよく見られますが、プログラミング言語としては必ず自分の存在価値があり、ある分野でその役割を果たしています.C++菜鳥が書いたプログラムの性能はJAVAの古い手書きのプログラムの性能が良いとは言えないが、プログラムの性能の良し悪しはプログラマーの功力にかかっていることがわかる.最近は『C++の性能を高めるプログラミング技術』を見ながら、役立つテクニックをまとめてブログに書いています.
(1)緩式構造
パフォーマンスの最適化は、柔軟性、保守性、拡張性、コスト、再利用など、他のソフトウェア目標を犠牲にすることが多い.パフォーマンスの問題を解決したり、他のソフトウェア開発目標を危険にさらすことなく高品質のコードを生成したりすることはめったにありませんが、オブジェクトが作成されても使用されないようにコードを調整してオーバーヘッドを解消することができます.
1つのコードスタイルは、コードブロックの先頭に使用するデータ型を定義し、C++で自然にすべてのオブジェクトを定義する習慣は浪費であり、以下のコードに示すように、オブジェクトaはbが本物の場合にのみ使用され、bが偽物の場合、aは全く使用されず、これは冗長なオーバーヘッドであり、aをifに移動すべきである.
A a;
if(b)
{
        a.run();
}

Cプログラマは、実行時のオーバーヘッドがないため、関数ブロックの先頭ですべての変数を定義する際に根拠がある傾向があります.C++言語の開始に伴い、C++専門家は変数の作成を最初の使用時まで遅らせるよう呼びかけてきたが、このような符号化エラーは実際の製品コードで発見される.
(2)冗長構造
次のクラスPersonのコンストラクション関数を考慮して、charポインタsを使用して標準ライブラリのstring変数nameに値を割り当てます.このコンストラクション関数が何をしたのかを見てみましょう.含まれるメンバー変数string nameはコンストラクション関数の初期化リストに表示されません.そのため、stringメンバー変数を正しく初期化するために、コンパイラはstringのデフォルトコンストラクション関数を呼び出すために呼び出しを挿入する必要があります.その後、name=sという文はstring::operator(const char*)を呼び出します.したがって、stringデフォルトコンストラクション関数を以前に呼び出すのは冗長と言える.
class Person
{
public:
	Person(const char *s){name = s;}
	...
private:
	string name;
};

Personコンストラクション関数をPerson(const char*s):name(s){}に変更すると、string nameを初期化するときにstring::string(const char*)というパラメータ付きコンストラクション関数が呼び出されますが、これは前のコンストラクション関数に比べてわずかなアップグレードしかありません.デフォルトのstringコンストラクション関数は非常に安価で、このような低効率はほとんど無視できます.しかし、このような細部は良いプログラミング習慣です.
今、私たちは元Personクラスのstringの代わりに自分のクラスSuperStringを使うことにしました.Superクラスの声明は以下の通りであり,実装は累述し,標準ライブラリstringの実装を参照できる.このクラスには、SuperString&operator=(const SuperString&s)というバージョンしかありません.パラメータはSuperStirngの参照です.
class SuperString
{
public:
	SuperString(const char *s = null);
	SuperString(const SuperString &s);
	SuperString & operator = (const SuperString & s);
	~SuperString();
private:
	char *str;
}

Personのコンストラクション関数でname=sは何をしましたか:nameのデフォルトコンストラクション関数を呼び出してから、一時的なSuperStringオブジェクトを作成します_tempは、割り当てオペレータ、呼び出しを満たすために使用されます.tempのパラメータはcharポインタの構造関数で、割り当てオペレータを呼び出して_tempはnameに割り当てられ、最後に呼び出されます.tempの構造関数.パラメータchar*sを満たすためにSuperStringに割り当てオペレータを再ロードすると、この一時変数の作成プロファイルのオーバーヘッドは完全に除去されたり、初期化パラメータテーブルを直接使用してchar*sでSuperStringを初期化したりして、この冗長なオーバーヘッドを除去することができます.
Person::Person(const char *s)
{
	name.SuperString::SuperString();
	
	SuperString _temp;
	_temp.SuperString::SuperString(s);
	
	name.SuperString::operator = (_temp);
	_temp.SuperString::~SuperString();
}

(3)まとめ
対象のライフサイクルは無償ではありません.オブジェクトの作成と明確化はCPUサイクルを消費します.オブジェクトを使用する予定がない限り、作成しないでください.通常、オブジェクトの作成を使用するブロックに延期します.
作成されたコードが実際に使用されていることを確認するには、作成されたオブジェクトとこれらのオブジェクトが実行する計算、たとえば一時的なオブジェクトの作成が削除できるかどうかを確認します.プログラマーが使用しているクラスに入ることを奨励します.この提案はOOPプレーヤーに歓迎されません.なにしろOOPの吹聴者はブラックボックスの実体をカプセル化するように使い、内幕を見ることを奨励しない.メンテナンス性と柔軟性を重視するアプリケーションもあれば、パフォーマンスを最も重要な位置に置く可能性があります.プログラマーとして、どの面を最大化すべきかを明らかにする必要があります.