[英]Arithmetic operations on vectors
Say I want to provide element-wise arithmetic operations operator+=
and operator+
for std::vector
to add vector entries element by element. 假设我想为元素提供逐元算术运算
operator+=
和operator+
for std::vector
以逐元素地添加向量条目。 Often, I see operator+
being implemented in terms of operator+=
like so: 通常,我看到
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;
}
In terms of performance, I guess 在性能方面,我猜
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;
}
is more efficient because it avoids initializing the copy of the first argument when entering the function but places the result directly into an uninitialized chunk of memory. 更有效,因为它避免在进入函数时初始化第一个参数的副本,但将结果直接放入未初始化的内存块中。 Is it really worth it to implement the second version or can I assume the compiler to optimize anyway?
是否真的值得实现第二个版本,还是我可以假设编译器进行优化? Also, I consider the second alternative less generic than the first one.
另外,我认为第二种替代品比第一种更不通用。 Imagine something like
想象一下
#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;
}
As with everything performance related: Profile the program, to see the what happens. 与一切性能相关: 简要介绍程序,看看会发生什么。
My guess is that the compiler will not optimize the code fully - and that it will probably never matter. 我的猜测是编译器不会完全优化代码 - 而且它可能永远不会重要。 The only way to know for sure is to try it out.
确切知道的唯一方法就是尝试一下。
Implementing +
in terms of +=
has the advantage that the two operations are known to be equivalent. 用
+=
实现+
的优点是已知这两个操作是等价的。 This makes it less likely for a bug to occur. 这使得错误发生的可能性降低。 You should make sure that your optimization is necessary, before you give up this advantage.
在放弃这一优势之前,您应该确保您的优化是必要的。 The idioms of C++ have usually become idioms for good reasons.
C ++的成语通常有很多原因成为习语。
Have you had a look at std::valarray
? 你看过
std::valarray
吗? It already provides those operation you need and you might benefit from SIMD. 它已经提供了您需要的操作,您可能会受益于SIMD。 Which might be a performance++ for free.
哪个可能是免费的性能++。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.