2010-11-29 12 views
6

Gemäß boost::tuple documentation hat der Zugriff auf ein einzelnes Element eines Tupels die gleiche Leistung wie der Zugriff auf eine Elementvariable. Zum Beispiel die folgende Erklärung gegeben:Boost-Tupel-Leistung

tuple<A, B, C> t1(A(), B(), C()); 
struct T { A a; B b; C c; } 
T t2; 

Diese beiden Aussagen sind gleich (oder mit vernachlässigbarer Unterschied) Leistung:

t1.get<2>(); 
t2.c; 

schaute ich in die Quellen von boost :: tuple und, wenn ich verstand sie richtig (ich bin nicht sicher, ich habe), get<N> Funktion diese Aktion tatsächlich durchführt:

in einer verknüpften Liste
C get<2>(tuple<A, B, C>& t) 
{ 
    return t.tail.tail.head; 
    //Generally: return t.tail. <<N times>> .head; 
} 

Das ist ähnlich wie bei einem Look-up als eine Richt ect-Zugang, und, soweit ich es erspähe, hat O (N) -Komplexität anstelle von O (1), was von einem Mitglied-Zugang erwartet wird. Von meinen früheren Erfahrungen mit Boost würde ich annehmen, dass ich es falsch verstanden habe; aber was ist mein Fehler? Wie funktioniert get wirklich?

+4

Ich rate das hängt stark von der Kompilierzeit Optimierung – Bwmat

Antwort

6

Sie haben die listenähnliche Leistung korrekt. Es kann jedoch zur Kompilierungszeit aufgelöst werden und läuft daher zur Laufzeit auf O (1) herunter. (Gegeben ein ausreichend guter optimierender Compiler.)

+0

Sie meinen, wenn ich die "Schwänze" in einer for-Schleife traversiere, ist es Laufzeit berechnet, aber wenn ich nur 't.tail.tail.tail schreiben. tail.tail.tail.tail.tail.head dann moderne Compiler können es zu einem direkten Zugriff auf das endgültige Element zu optimieren? Gibt es einen einfachen Weg zu wissen, was mein Compiler damit macht? – FireAphis

+0

Welche Compiler führen diese Optimierung tatsächlich durch? – Crashworks

+0

Eine Schleife kann so gut sein, wenn sie vom Optimierer ordnungsgemäß entrollt werden kann. Beachten Sie, dass es sich um eine Struktur handelt, bei der es sich hier um eine Konstante für die Kompilierungszeit handelt, und nicht um eine normale dynamische Datenstruktur. – ltjax

3

Denken Sie daran, in C++ ist der Punktoperator keine Zeigerabweichung, sondern eine direkte Offsetberechnung. Die allgemeine Antwort ist ja, i1.i2.i3.in für alle n ist eine konstante Zeitoperation, die zur Kompilierzeit berechnet werden kann.

Wenn Sie sehr tief, ein wenig über die Compiler-Interna für diese lernen wollen schauen, ohne graben auf LLVM getelementptr http://llvm.org/docs/LangRef.html#i_getelementptr Das ist genau, wie ein C++ Compiler wie CLANG LLVM würde Ziel, wenn eine Struktur Bezug zu kompilieren.