2012-09-13 3 views
6

In dem Beispielcode unten zuteile ich einige Instanzen des Struct Chunk. In den for-Schleifen iteriere ich dann durch den Speicherblock und greife auf die verschiedenen Instanzen zu, indem ich entweder Zeiger oder Referenzen verwende, und weise ihnen einige zufällige Daten zu.Was ist schneller, Zeigerzugriff oder Referenzzugriff?

Aber welche for-Schleife wird am schnellsten ausgeführt? Nach meinem Wissen würde ich sagen, dass die Referenzschleife am schnellsten ist, da sie keine Dereferenzierung erfordert und direkten Zugriff auf die Instanz im Speicher hat. Wie falsch/richtig bin ich?

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; 
} 
+7

Hängt von Ihrem Compiler ich denke, aber mit mir kompilieren sie auf den gleichen Code. Die meisten C++ - Entwickler bevorzugen Referenzen als eine Frage des Stils. –

+0

Denken Sie daran, dass eine Referenz wie ein automatisch de-referenzierter Zeiger ist. – tadman

+0

@tadman Nicht gemäß der Norm. –

Antwort

10

Sie sollten die gleichen (nicht etwa die gleichen, aber genau die gleichen) mit jedem nicht-idiotischen Compiler. Unter der Haube, Referenzen sind Zeiger (auf 99% der Compiler). Es gibt keinen Grund für einen Unterschied.

Pedantic: die zweite Schleife könnte schneller sein (wahrscheinlich nicht), weil die Daten bereits im Cache sind, aber das ist es. :)

+0

Erklärung für den Downvote? –

+0

Wahrscheinlich ein C-Fanatiker, der Pfeile lieber mag als Ampersands. – tadman

+2

Nicht 100% richtig. Referenzen sind keine Zeiger, sie sind überhaupt keine Objekte. Sie könnten durch Zeiger in mehreren Fällen implementiert werden, aber nicht zu 100%. Und der Code, der für Zeiger und als Referenz generiert wird, kann sich unterscheiden. – Rost

1

Es sollte keinen Unterschied im Code geben, der von irgendeinem annehmbaren Compiler produziert wird.

1

Wenn Sie zwischen zwei Versionen des Codes wie die in Ihrem Beispiel zögern, sollten Sie die eine besser lesbar wählen. Mögliche Optimierungen der von Ihnen vorgeschlagenen Art sollen vom Compiler vorgenommen werden.

Besser lesbar in Ihrem Fall ist eher die Version mit Referenzen (eigentlich, vielleicht nicht wirklich lesbarer, aber der Konsens ist es, die Verwendung von Referenzen zu bevorzugen, weil Zeiger "gefährlicher" sind).

Aber zurück zur Effizienz: (bitte, wenn jemand Assembler kennt, hört besser auf zu lesen oder riskiert einen Lachangriff ...) Meiner Meinung nach muss der Compiler das pData kompilieren, da die pData auf dem Heap gespeichert ist Zeiger sowieso verwenden. Ich denke, dass Ihre Argumentation irgendwie korrekt sein könnte, wenn Ihre Struktur nur mit "Chunk data [8];" auf dem Stack zugewiesen wurde. Spätestens aber bei den Compiler-Optimierungen sollte der Unterschied trotzdem gelöscht werden.

1

Ich bin versucht zu sagen: Wen kümmert es? Jeder Unterschied in der Geschwindigkeit wird vernachlässigbar sein, und Sie sollten die am besten lesbaren wählen. In diesem speziellen Fall würde ich erwarten, genau den gleichen Code zu sehen, der in beiden Fall generiert wird. In komplizierteren Fällen kann der Compiler später in der Schleife nicht feststellen, dass der Zeiger nicht erneut eingefügt wurde, und muss möglicherweise erneut gelesen werden. Aber damit dies der Fall ist, müssten Sie genug andere Dinge tun, dass der Unterschied nicht messbar wäre.

+0

Vielen Dank für Ihre Antwort. Dies ist, wie Sie vielleicht bemerken, kein Beispiel aus der realen Welt. Ich frage mich nur, was ich in einem komplexeren Szenario wählen sollte. –

+0

@MichaelMancilla Was auch immer das Beste ausdrückt, was Sie tun möchten. Im Allgemeinen Verweis wenn möglich und Zeiger anders. Die Verwendung von Verweis teilt dem Leser (und dem Compiler) mit, dass das Objekt, auf das verwiesen wird, nicht geändert wird. –

+0

"Jeder Geschwindigkeitsunterschied wird vernachlässigbar sein." Ihr Anwendungsfall ist nicht irgendeines. – easytiger