Was macht Zeiger schneller als Arrays?

8

Ich googelte und fand die folgende Syntax für Zeiger

%Vor%

Ich wusste nicht, dass Pointer auch in der Array-Form erreichbar sind. Ich habe * für Zeigeroperationen verwendet Ich habe eine [0] für Arrays und * p für Zeigeroperationen verwendet, weshalb ich die anderen 2 Dinge nicht kannte. Nun können wir von oben auf das zweite Element des Arrays auf eine der folgenden Arten zugreifen:

%Vor%

Nun frage ich mich: Was ist die schnellere Operation? Ich habe gelesen, dass Operationen mit Zeigern schneller sind, und deshalb bleibt C an der Spitze für eine schnelle Ausführung und keine andere Sprache kann ihre Schnelligkeit übertreffen.

Nun die eigentliche Frage: Was macht die Zeigeroperationen schneller?

1) * (p + 0) der * (Wert bei Adresse), der den Trick macht oder

2) p [0]

seit wir

verwenden %Vor%

wenn ein normales Array als * (a + 1) (welches den * Wert bei der Adresse verwendet) wie ein Zeiger verwendet werden kann. Warum verwenden wir Zeiger für schnellere Operationen? Wenn beide die gleiche Syntax haben, wenn normale Arrays und Pointer * in diesen Syntaxen verwenden, warum Zeiger schneller sind?

Aber bitte sagt mir, warum wir Zeiger benutzen? Mein Professor hat mir gesagt, dass Zeiger schneller sind, weil sie auf eine Variable verweisen, die eher an der Stelle gesucht werden sollte.

    
niko 31.08.2011, 17:35
quelle

6 Antworten

8

Ich würde tatsächlich nicht erwarten, dass *(ptr + offset) schneller ist als ptr[offset] . Tatsächlich werden auf meinem Computer die folgenden Funktionen in genau demselben Assembly-Code kompiliert:

%Vor%

was (aufgeräumt) aussieht wie folgt:

%Vor%

(gcc 4.5.0, x86_64, keine Optimierungen). Oder mit -O3

%Vor%     
Dirk 31.08.2011, 17:51
quelle
3

Der Array-Zugriff ist schneller, wenn das Array im lokalen Stack-Bereich oder im statischen Speicher zugeordnet ist, da auf diesen direkt über einen Offset des Wertes im EBP -Register oder über einen direkten Offset von einer festen Adresse zugegriffen werden kann als zu versuchen, auf den Wert eines Zeigers in einer Stapelvariablen zuzugreifen und dann den Wert dieser Variablen zu addieren und zu dereferenzieren.

Wenn Sie beispielsweise ein Array wie:

schreiben %Vor%

Um auf den Wert in array[3] zuzugreifen, gibt der Compiler nur einen einfachen Befehl aus (wie für x86):

%Vor%

Das liegt daran, dass wir, wenn wir uns den Stack anschauen, folgendes sehen würden:

%Vor%

Um auf den Wert von array[3] zuzugreifen, wird nur eine Anweisung benötigt. Das ist sehr schnell.

    
Jason 31.08.2011 17:38
quelle
1

In den von Ihnen angegebenen Beispielen ist p[1] nicht schneller als a[1] .

    
hamstergene 31.08.2011 17:41
quelle
0

Ein Array-Name ist im Wesentlichen der Zeiger auf das erste Element dieses Arrays - sie sollten also ziemlich gleich sein.

Statisch erzeugte Arrays haben einen eigenen Typ, der die definierte Größe der Kompilierzeit enthält, was sie technisch von den Zeigern unterscheidet, aber für alle intensiven Zwecke können der Array-Name und der Zeichenzeiger in Ihrem Beispiel identisch verwendet werden.

    
John Humphreys - w00te 31.08.2011 17:40
quelle
0

Array ist ein Zeiger, es gibt keinen Unterschied zwischen p und a nach

%Vor%

Sowohl a als auch p sind ein Zeiger auf char und verweisen auf den gleichen Platz - Anfang Ihres Arrays im Speicher .

mit "operator []" entspricht auch der Zeigerarithmetik

%Vor%

wird durch

ersetzt %Vor%

bedeutet, dass der Zeiger auf den Anfang des Arrays um i * sizeof (char) an die Stelle des i-ten Elements Ihres Arrays verschoben wird.

Der tatsächliche Zeitunterschied wird angezeigt, wenn Sie versuchen, alle Elemente zu durchlaufen, z. B. den String kopieren:

%Vor%

erzeugt Arithmetik wie b + i (aka b Verschiebung um i * sizeof (char)) und a + i (aka eine Verschiebung um i * sizeof (char)) für jede Iteration der Schleife und

%Vor%

ist frei von diesen Berechnungen, Sie verschieben nur jeweils zwei Zeiger nach Größe von char.

    
Nick 31.08.2011 17:49
quelle
-1

Zeiger, die schneller als Arrays sind, stammen aus dem folgenden Beispiel.

Angenommen, Sie möchten die strcpy -Funktion implementieren, d. h. eine mit Null beendete Zeichenfolge in eine andere kopieren. Schauen wir uns zwei Beispiele an:

Erster:

%Vor%

Zweiter:

%Vor%

Das zweite Beispiel wird effizienter implementiert, da es bei jeder Iteration weniger Speichermodifikationen vornimmt und Zeiger anstelle von Arrays verwendet. Aber es gibt zwei Dinge:

  1. Es sind keine schnellen Zeiger, deren Algorithmus sie zur Optimierung benutzt.
  2. Optimizer kann diese Art der Optimierung problemlos automatisch durchführen, so dass Sie wahrscheinlich sowieso den gleichen generierten Code erhalten.
unkulunkulu 31.08.2011 17:46
quelle

Tags und Links