2016-05-19 18 views
0

Nehmen wir an, ich meine eigenen Vektor-Klasse erstellen, wie folgt:Performance Operator vs Funktionsaufruf Überlastung

<template class T> 
class Vector { 
private: 
    void** ptr; 
    // More functions implementing the custom vector 
public: 
    T& operator[](int iIndex) const { 
    return *(T*)ptr[iIndex]; 
    } 
    T& Item(int iIndex) const { 
    return *(T*)ptr[iIndex]; 
    } 
} 

Lassen Sie sagen, ich habe eine Vector<someClass> v. Streng, leistungsmäßig, welche von diesen ist schneller für den Zugriff auf ein Element des Vektors.

  1. v.Item(i)
  2. v[i]
+0

Vernachlässigbarer Unterschied, falls vorhanden. – erip

+3

Der Operator-Aufruf verhält sich hier wie jeder andere Funktionsaufruf. Beide Funktionen haben dieselbe effektive Funktionssignatur. Warum sollten Sie einen Leistungsunterschied erwarten? – mindriot

+0

Wie oben erwähnt, erzeugt der Operator einen Funktionsaufruf unter der Haube. Darüber hinaus werden sie wahrscheinlich in der optimierten binären inline, so dass sie genau die gleiche Baugruppe und damit die exakt gleiche Leistung generieren –

Antwort

7

v[i] ist nur syntaktischer Zucker für v.operator[](i).

Es wird keinen Unterschied in der Leistung geben, sofern zwischen zwei Funktionen mit unterschiedlichen Namen, die in allen anderen Punkten identisch sind, kein Leistungsunterschied besteht.

1

zu @ Bathsebas Antwort hinzuzufügen, ich Vector Implementierung hätte einen schnellen Test mit einer etwas umfassenderes Dummy:

template <class T> 
class Vector { 
private: 
    T* ptr; 
public: 
    Vector(int size) 
    : ptr(new T[size]) 
    { } 
    ~Vector() 
    { 
    delete[] ptr; 
    } 
    T& operator[](int iIndex) const { 
    return ptr[iIndex]; 
    } 
    T& Item(int iIndex) const { 
    return ptr[iIndex]; 
    } 
}; 

int main() 
{ 
    Vector<int> v(5); 
    v[0] = 3; 
    v.Item(1) = 4; 
} 

mit g++ -S Zusammengestellt, I get exactly identical assembly for both methods (suchen Sie nach _ZNK6VectorIiEixEi = Vector<int>::operator[](int) const und _ZNK6VectorIiE4ItemEi = Vector<int>::Item(int) const in der Baugruppe Ausgabe). Dies ist zu erwarten, da sowohl operator[]() als auch Item() Funktionsaufrufe sind. Die Operatornotation ist nur syntaktischer Zucker.

1

Wie in den Kommentaren und in der anderen Antwort gesagt, keinen Unterschied.

Operator generiert einen Aufruf an Operator, und da diese beiden Funktionen den gleichen Code haben, generieren sie die gleiche Assembly und damit die gleiche Leistung.

Aus Gründen der Vollständigkeit, habe ich versucht, mit Klirren 3.7 auf dem folgenden Eingabecode:

template <typename T> 
class Vector { 
private: 
    void** ptr; 


public: 

    Vector(void** _ptr): ptr(_ptr) {} 

    T& operator[](const int iIndex) const { 
    return *(T*)ptr[iIndex]; 
    } 

    T& Item(const int iIndex) const { 
    return *(T*)ptr[iIndex]; 
    } 
}; 

extern "C" int printf(const char* format, ...); 

int main() { 
    double a[2] = { 1.0, 2.0 }; 
    Vector<double> va((void**) &a); 

    double a1 = va[0]; 
    printf("%lf\n", a1); 
    double a2 = va.Item(0); 
    printf("%lf\n", a2); 
} 

zusammengestellt mit:

clang -O3 -g -S -emit-llvm main.cpp -o main.ll 

es erzeugt effektiv exakt die gleichen Linien:

; Function Attrs: nounwind uwtable 
define i32 @main() #0 { 
entry: 
    %a.sroa.0.0.copyload = load double*, double** bitcast ([2 x double]* @_ZZ4mainE1a to double**), align 16, !dbg !57 
    %0 = load double, double* %a.sroa.0.0.copyload, align 8, !dbg !66, !tbaa !67 
    %call1 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), double %0), !dbg !72 
    %1 = load double, double* %a.sroa.0.0.copyload, align 8, !dbg !76, !tbaa !67 
    %call3 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), double %1), !dbg !78 
    ret i32 0, !dbg !79 
} 
+1

Ich war absichtlich süß, als ich mein "insofern" -Bit in meiner Antwort erwähnte: in * interpretiert * C++ konnte * ein Unterschied sein, wenn eine Funktion einen längeren Namen hatte als die andere! – Bathsheba