我有这个功能
int add(T a, T b)
{
return a.blah +b.blah;
}
我想重载加号运算符,我必须选择(当然,在这种情况下,加号运算符已经完成了以下代码所做的事情)
选项1:
int operator+(T lhs, T rhs)
{
return add(a,b);
}
选项2:
int operator+(T lhs, T rhs)
{
return a.blah+b.blah;
}
这些定义中的任何一个是否具有优于另一个的性能优势?我想要实现的功能对STL容器的元素执行更复杂的操作。
答案 0 :(得分:1)
使用选项1,不要重复自己。确保编译器在定义operator +时看到add的定义,以便它可以内联代码。打开优化后,生成的代码绝对没有区别。
struct T
{
int blah;
};
int add(T a, T b)
{
return a.blah +b.blah;
}
int operator+(T lhs, T rhs)
{
return add(lhs, rhs);
}
GCC生成:
add(T, T):
lea eax, [rdi+rsi]
ret
operator+(T, T):
lea eax, [rsi+rdi]
ret
Clang和Microsoft编译器生成相同的代码。
如果代码更复杂且编译器拒绝将add
内联到operator+
,请考虑使用operator +内联函数。然后它将被内联,因为它只进行一次调用,调用者将直接调用add
而无需额外的开销。
通常的警告:你当然应该一如既往地进行基准测试,看看是否有任何真正的差异和配置文件,看看是什么导致了差异,同时查看生成的代码以检查优化是否按预期执行:-)
答案 1 :(得分:1)
选项1更好,因为您没有复制代码。
可能更好的是通过常量引用传递T来避免值复制。