Search code examples
c++11eigen

Eigen cast with auto return type - Less efficient than explicit return type?


When casting a vector integers (i.e. Eigen::VectorXi) to a vector of doubles, and then operating on that vector of doubles, the generated assembly is dramatically different if the return type of the cast is auto.

In other words, using:

    Eigen::VectorXi int_vec(3);
    int_vec << 1, 2, 3;

    Eigen::VectorXd dbl_vec = int_vec.cast<double>();

Compared to:

    Eigen::VectorXi int_vec(3);
    int_vec << 1, 2, 3;

    auto dbl_vec = int_vec.cast<double>();

Here are two examples on godbolt:

VectorXd return type: https://godbolt.org/z/0FLC4r

auto return type: https://godbolt.org/z/MGxCaL

What are the ramifications of using auto for the return here? I thought it would be more efficient by avoiding a copy, but now I'm not sure.


Solution

  • Indeed, in your code in the question you avoid a copy (indeed, until dbl_vec is used, it's essentially a noop). However, in the code on godbolt, you traverse the original int_vec and evaluate dbl_vec at least twice, possibly thrice:

    max + std::log((dbl_vec.array() - max)
    ^^^             ^^^^^^^           ^^^
    

    I'm not sure if the two calls to max are collapsed into a temporary or not. I'd hope so.

    In any case, kmdreko is right and you should avoid using auto with Eigen unless you know exactly what you're doing. In this case, the auto is an expression template that does not get evaluated until used. If you use it more than once, then it gets evaluated more than once. If the evaluation is expensive, then the savings from not using a copy are lost (with interest) to the additional evaluation times.