0

私は長い間C++をプログラミングしてきたので、これを知らないのはばかげていますが...

私はパフォーマンスが重要なコードを頻繁に書きますが、そのときはできるだけヒープ割り当てを避けるようにしています。そのために、個々のオブジェクトごとに new と delete を呼び出す代わりに、事前に割り当てられた小さなオブジェクトの配列を再利用することがよくあります。

そのような場合、私は通常これを行います:

class MyClass
{
private:
    int x, y;

public:
    inline void Set(_x, _y) { x = _x; y = _y; }
};

...

MyClass &objectToReuse = someArray[someIndex];

objectToReuse.Set(someXValue, someYValue);

ただし、この見栄えの良いバージョンでも同じコードが生成されるのではないかと思います。

class MyClass
{
private:
    int x, y;

public:
    inline MyClass(_x, _y) : x(_x), y(_y) {}
};

...

MyClass &objectToReuse = someArray[someIndex];

objectToReuse = MyClass(someXValue, someYValue);

最新の C++ コンパイラはこれを「取得」しますか、それとも一時オブジェクトを構築してからコピーしますか?

4

1 に答える 1

1

はい、優れたコンパイラは、この場合の余分なオーバーヘッドを排除します。

私が「この場合」と言ったのは、コンストラクター (および代入演算子 - 以下の「コンストラクター/構築」と表示されている場合は、「または代入演算子」と読みます) で何が起こるかに大きく依存するためです。コンストラクターが影響する場合 (またはグローバル状態に影響を与える可能性がある場合、コンパイラは構造を削除できません.グローバル状態に影響を与えるのは、ファイルの読み取りまたは書き込み、グローバル変数の更新、コンパイラが「知らない」(知らない)関数へのほとんどすべての呼び出しです。 't have the source code for) により、コンストラクター/コピーの削除が「失敗」します。

当然、コンストラクター/コピーが排除されない場合は、setter を使用したコードの方が効率的である可能性があります。実際のシナリオでの正確な測定値は、ベンチマークによってのみ実際に決定できます。最適化を使用してコンパイルしたときに、1 行または複数行のコードが実際にどのような影響を与えるかを正確に判断するのは難しいことが多いためです。複雑に見えるものも可能です (ただし、それほど頻繁ではありませんが、最終的にはまったく時間がかかりません。

于 2013-07-24T11:18:23.867 に答える