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

后端 未结 22 2375
南方客
南方客 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:19

    This is an old but popular question.

    At this point, many programmers will be working in C++11. And in C++11 the OP's code as written runs equally fast for UseArray or UseVector.

    UseVector completed in 3.74482 seconds
    UseArray completed in 3.70414 seconds
    

    The fundamental problem was that while your Pixel structure was uninitialized, std::vector::resize( size_t, T const&=T() ) takes a default constructed Pixel and copies it. The compiler did not notice it was being asked to copy uninitialized data, so it actually performed the copy.

    In C++11, std::vector::resize has two overloads. The first is std::vector::resize(size_t), the other is std::vector::resize(size_t, T const&). This means when you invoke resize without a second argument, it simply default constructs, and the compiler is smart enough to realize that default construction does nothing, so it skips the pass over the buffer.

    (The two overloads where added to handle movable, constructable and non-copyable types -- the performance improvement when working on uninitialized data is a bonus).

    The push_back solution also does fencepost checking, which slows it down, so it remains slower than the malloc version.

    live example (I also replaced the timer with chrono::high_resolution_clock).

    Note that if you have a structure that usually requires initialization, but you want to handle it after growing your buffer, you can do this with a custom std::vector allocator. If you want to then move it into a more normal std::vector, I believe careful use of allocator_traits and overriding of == might pull that off, but am unsure.

提交回复
热议问题