简体   繁体   English

向量的算术运算

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM