假设我想为operator+=
提供逐元素算术运算operator+
和std::vector
,以逐元素地添加向量条目。通常情况下,我认为operator+
正在operator+=
执行,如此:
#include <algorithm>
#include <vector>
template<class Type>
std::vector<Type> & operator+=(std::vector<Type> &x, const std::vector<Type> &y) {
// Checks for equal size of x and y omitted here...
std::transform(std::begin(x), std::end(x), std::begin(y), std::begin(x), std::plus<Type>());
return x;
}
template<class Type>
std::vector<Type> operator+(std::vector<Type> x, const std::vector<Type> &y) {
// Checks for equal size of x and y omitted here...
return x += y;
}
int main() {
std::vector<double> v0{1.0, 2.0, 3.0};
auto v1 = v0;
auto v2 = v0;
v2 += v0; // yields [2, 4, 6]
auto v3 = v0 + v1; // yields [2, 4, 6]
return 0;
}
就性能而言,我猜
template<class Type>
std::vector<Type> operator+(const std::vector<Type> &x, const std::vector<Type> &y) {
// Checks for equal size of x and y omitted here...
std::vector<Type> result;
result.reserve(x.size());
std::transform(std::begin(x), std::end(x), std::begin(y), std::back_inserter(result), std::plus<Type>());
return result;
}
更有效,因为它避免在进入函数时初始化第一个参数的副本,但将结果直接放入未初始化的内存块中。是否真的值得实现第二个版本,还是我可以假设编译器进行优化?另外,我认为第二种替代品比第一种更不通用。想象一下像
#include <array>
#include <type_traits>
template<class Container, class Enable = void>
struct IsSequenceContainer: public std::false_type {
};
template<>
template<class Type, std::size_t size>
struct IsSequenceContainer<std::array<Type, size> >: public std::true_type {
};
template<>
template<class Type, class Allocator>
struct IsSequenceContainer<std::vector<Type, Allocator> >: public std::true_type {
};
// Use the following operations for std::array and std::vector
template<class Container>
typename std::enable_if<IsSequenceContainer<Container>::value, Container>::type operator+(Container x, const Container &y) {
return x += y;
}
答案 0 :(得分:3)
与所有与绩效相关的内容:对程序进行概要分析,了解会发生什么。
我的猜测是编译器不会完全优化代码 - 而且它可能永远不会重要。确切知道的唯一方法就是尝试一下。
根据+
实施+=
的优势在于已知两个操作是等效的。这使得错误发生的可能性降低。在放弃这一优势之前,您应该确保您的优化是必要的。 C ++的成语通常有很多原因成为习语。
答案 1 :(得分:1)
你看过std::valarray
了吗?它已经提供了您需要的操作,您可能会受益于SIMD。这可能是免费的性能++。