问题
Let us suppose I create my own vector class as follows:
<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];
}
}
Let say, I have a Vector<someClass> v
. Strictly, performance-wise which of these is faster for accessing an element of the vector.
v.Item(i)
v[i]
回答1:
v[i]
is merely syntactic sugar for v.operator[](i)
.
There will be no difference in performance, insofar that there is no difference in performance between two functions with different names that are identical in all other respects.
回答2:
To add to @Bathsheba's answer, I did a quick test with a slightly more complete dummy Vector
implementation:
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;
}
Compiled with g++ -S
, I get exactly identical assembly for both methods (look for _ZNK6VectorIiEixEi
= Vector<int>::operator[](int) const
and _ZNK6VectorIiE4ItemEi
= Vector<int>::Item(int) const
in the assembly output). This is expected, since both operator[]()
and Item()
are function calls. The operator notation is just syntactic sugar.
回答3:
As said in comments an in the other response, no difference at all.
operator will generate a call to operator, and since those two functions have the same code, they generate the same assembly, hence yielding the exact same performance.
For the sake of completeness, I tried with clang 3.7 on the following input code:
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);
}
compiled with:
clang -O3 -g -S -emit-llvm main.cpp -o main.ll
it effectively generates the exact same lines:
; 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
}
来源:https://stackoverflow.com/questions/37322423/performance-of-operator-overloading-vs-function-call