Is std::vector so much slower than plain arrays?

后端 未结 22 2370
南方客
南方客 2020-11-22 12:00

I\'ve always thought it\'s the general wisdom that std::vector is \"implemented as an array,\" blah blah blah. Today I went down and tested it, and it seems to

22条回答
  •  有刺的猬
    2020-11-22 12:36

    Martin York's answer bothers me because it seems like an attempt to brush the initialisation problem under the carpet. But he is right to identify redundant default construction as the source of performance problems.

    [EDIT: Martin's answer no longer suggests changing the default constructor.]

    For the immediate problem at hand, you could certainly call the 2-parameter version of the vector ctor instead:

    std::vector pixels(dimension * dimension, Pixel(255, 0, 0));
    

    That works if you want to initialise with a constant value, which is a common case. But the more general problem is: How can you efficiently initialise with something more complicated than a constant value?

    For this you can use a back_insert_iterator, which is an iterator adaptor. Here's an example with a vector of ints, although the general idea works just as well for Pixels:

    #include 
    // Simple functor return a list of squares: 1, 4, 9, 16...
    struct squares {
        squares() { i = 0; }
        int operator()() const { ++i; return i * i; }
    
    private:
        int i;
    };
    
    ...
    
    std::vector v;
    v.reserve(someSize);     // To make insertions efficient
    std::generate_n(std::back_inserter(v), someSize, squares());
    

    Alternatively you could use copy() or transform() instead of generate_n().

    The downside is that the logic to construct the initial values needs to be moved into a separate class, which is less convenient than having it in-place (although lambdas in C++1x make this much nicer). Also I expect this will still not be as fast as a malloc()-based non-STL version, but I expect it will be close, since it only does one construction for each element.

提交回复
热议问题