11

以下のサンプルコードでは、structChunkのいくつかのインスタンスを割り当てています。次に、forループでメモリブロックを反復処理し、ポインタまたは参照を使用してさまざまなインスタンスにアクセスし、ランダムデータを割り当てます。

しかし、どのforループが最も速く実行されますか?私の知る限り、参照ループは逆参照を必要とせず、メモリ内のインスタンスに直接アクセスできるため、最速になると思います。私はどれほど間違っている/正しいですか?

struct Chunk {
    unsigned int a;
    float b;
    const char* c;
};

int main() {
    Chunk* pData = new Chunk[8];

    for( unsigned int i = 0; i < 8; ++i ) {
        Chunk* p = &pData[i];
        p->a = 1;
        p->b = 1.0f;
        p->c = "POINTERS";
    }

    for( unsigned int i = 0; i < 8; ++i ) {
        Chunk& r = pData[i];
        r.a = 1;
        r.b = 1.0f;
        r.c = "REFERENCES";
    }

    delete [] pData;
    return 0;
}
4

5 に答える 5

13

それらは、非ばかげたコンパイラと同じである必要があります(ほぼ同じではありませんが、まったく同じです)。内部的には、参照ポインターです(99%のコンパイラー)。違いはありません。

衒学者:データがすでにキャッシュにあるため、2番目のループはより高速になる可能性があります(おそらくそうではありません)が、それだけです。:)

于 2012-09-13T14:11:32.917 に答える
2

私は言いたくなります:誰が気にしますか?速度の違いは無視できるものであり、最も読みやすいものを選択する必要があります。この特定のケースでは、両方のケースでまったく同じコードが生成されることが期待されます。より複雑なケースでは、コンパイラはループの後半でポインターが再配置されていないことを判断できず、ポインターを再読み取りする必要がある場合があります。しかし、これが事実であるためには、違いが測定できないほど十分に他のことをしなければなりません.

于 2012-09-13T14:41:54.037 に答える
1

例のような2つのバージョンのコードの間で躊躇する場合は、より読みやすいバージョンを選択する必要があります。あなたが提案する種類の可能な最適化は、コンパイラによって行われることになっています。

あなたの場合、より読みやすいのは、むしろ参照付きのバージョンです(実際には、実際には読みにくいかもしれませんが、ポインターはより「危険」であるため、コンセンサスは参照の使用を優先することです)。

しかし、効率に戻りましょう:(誰かがアセンブラーを知っている場合は、読むのをやめるか、笑い攻撃の危険を冒してください...)私の意見では、pDataはヒープに配置されているため、コンパイラーはとにかくポインターを使用してコンパイルする必要があります。「チャンクデータ[8];」だけで構造がスタックに割り当てられていれば、あなたの推論はある程度正しいと思います。しかし、遅くともコンパイラの最適化が行われているときは、とにかく違いを削除する必要があります。

于 2012-09-13T14:33:59.693 に答える
1

まともなコンパイラによって生成されたコードに違いはないはずです。

于 2012-09-13T14:12:59.090 に答える