std::vector reserve() and push_back() is faster than resize() and array index, why?

I was doing a quick performance test on a block of code

void ConvertToFloat( const std::vector< short >& audioBlock, 
                     std::vector< float >& out )
{
    const float rcpShortMax	= 1.0f / (float)SHRT_MAX;
    out.resize( audioBlock.size() );
    for( size_t i = 0; i < audioBlock.size(); i++ )
    {
    	out[i]	= (float)audioBlock[i] * rcpShortMax;
    }
}

I was happy with the speed up over the original very naive implementation it takes just over 1 msec to process 65536 audio samples.

However just for fun I tried the following

void ConvertToFloat( const std::vector< short >& audioBlock, 
                     std::vector< float >& out )
{
    const float rcpShortMax	= 1.0f / (float)SHRT_MAX;
    out.reserve( audioBlock.size() );
    for( size_t i = 0; i < audioBlock.size(); i++ )
    {
    	out.push_back( (float)audioBlock[i] * rcpShortMax );
    }
}

Now I fully expected this to give exactly the same performance as the original code. However suddenly the loop is now taking 900usec (i.e. it’s 100usec faster than the other implementation).

Can anyone explain why this would give better performance? Does resize() initialize the newly allocated vector where reserve just allocates but does not construct? This is the only thing I can think of.

PS this was tested on a single core 2Ghz AMD Turion 64 ML-37.

Why doesn’t this vector assignment work?

Similar Questions: STL vector reserve() and copy() std::vector reserve() and push_back() is faster than resize() and array index, why? std::vector::resize() vs. std::vector::reserve() #include <

How come my array index is faster than pointer

Why the array index is faster than pointer? Isn’t pointer supposed to be faster than array index? ** i used time.h clock_t to tested two functions, each loop 2 million times. Pointer time : 0.018995

Why is array.index faster than array.include?

I’m working with some large datasets, and trying to improve performance. I need to determine whether an object is contained in an array. I was considering using either index or include?, so I benchmar

Java: why Array (w index) *order of magnitude* faster than Map (key) access?

We ran the attached test. The results consistently show that access via Array by index is 10x faster than access via Map by key. This order of magnitude difference surprised us. Our key for the Map is

Why is .index faster than .all?

Here are two simple blocks that do the same thing: a = (0..100).to_a a.all? do |x| !(x == 1000) end nil == a.index do |x| x == 1000 end Except that the second one is consistently a little bit faster.

Why is === faster than == in PHP?

Why is === faster than == in PHP?

std::strings’s capacity(), reserve() & resize() functions

I wan to use std::string simply to create a dynamic buffer and than iterate through it using an index. Is resize() the only function to actually allocate the buffer? I tried reserve() but when I try t

Why is processing a sorted array not faster than an unsorted array in Python?

In this post Why is processing a sorted array faster than random array, it says that branch predicton is the reason of the performance boost in sorted arrays. But I just tried the example using Python

Why is looping through an Array so much faster than JavaScript’s native `indexOf`?

Why is looping through an Array so much faster than JavaScript’s native indexOf? Is there an error or something that I’m not accounting for? I expected native implementations would be faster. For Loo

PHP why is echo faster than print

In PHP, why is echo faster than print They do the same thing… Why is one faster than the other? Do they do exactly the same thing???

Answers

Does resize initialize the newly allocated vector where reserve just allocates but does not construct?

Yes.

out.resize( audioBlock.size() );

Since out’s size (= 0) is lesser than audioBlock.size() , additional elements are created and appended to the end of the out. This creates the new elements by calling their default constructor.

Reserve only allocates the memory.

First code writes to out[i] which boils down to begin() + i (ie. an addition). Second code uses push_back, which probably writes immediately to a known pointer equivalent to end() (ie. no addition). You could probably make the first run as fast as the second by using iterators rather than integer indexing.

Edit: also to clarify some other comments: the vector contains floats, and constructing a float is effectively a no-op (the same way declaring “float f;” does not emit code, only tells the compiler to save room for a float on the stack). So I think that any performance difference between resize() and reserve() for a vector of floats is not to do with construction.

Resize()

Modifies the container so that it has exactly n elements, inserting elements at the end or erasing elements from the end if necessary. If any elements are inserted, they are copies of t. If n > a.size(), this expression is equivalent to a.insert(a.end(), n – size(), t). If n < a.size(), it is equivalent to a.erase(a.begin() + n, a.end()).

Reserve()

If n is less than or equal to capacity(), this call has no effect. Otherwise, it is a request for allocation of additional memory. If the request is successful, then capacity() is greater than or equal to n; otherwise, capacity() is unchanged. In either case, size() is unchanged.

Memory will be reallocated automatically if more than capacity() – size() elements are inserted into the vector. Reallocation does not change size(), nor does it change the values of any elements of the vector. It does, however, increase capacity()

Reserve causes a reallocation manually. The main reason for using reserve() is efficiency: if you know the capacity to which your vector must eventually grow, then it is usually more efficient to allocate that memory all at once rather than relying on the automatic reallocation scheme.