Most efficient way of copying a raw byte array into an empty byte vector
Solution 1
If you don't need to create the vector before the copy takes place, you could always pass the raw array to the constructor of your vector:
std::vector<uint8_t> myVector(myRawArray, myRawArray + byteCount);
If you do need to construct the vector beforehand, the following is an option:
std::vector<uint8_t> myVector;
// ... do some stuff ...
// Now, we're ready for the copy, and byteCount is known.
myVector.reserve(byteCount);
std::copy(myRawArray, myRawArray + byteCount, std::back_inserter(myVector));
I would suggest using std::copy unless memcpy is proven to be faster. std::copy is safer and more idiomatic in C++ code, but don't be afraid to use memcpy if it really is proven to be faster. The speed difference will most likely change with different compilers.
I hope this helps.
Solution 2
memcpy()
is usually written in assembly and it is very optimized so you should know that memcpy
will be fast. vector::insert
is usually implemented as having a call to memcpy
under the hood but it does need to check if there is enough space in the vector for the insertions to take place without any reallocations. I have not profiled this but I bet the first version with the call to reserve
is faster.
An alternative to this would be to use std::copy
which has been found to be slightly faster than using memcpy
in some cases, you can be sure that if possible it also makes a call to memcpy
or does something better. So performance issues should not be a problem with it. It will also take care of increasing the size of the vector to match your requirement.
mk33
Updated on June 20, 2022Comments
-
mk33 almost 2 years
I have a scenario in which I need to copy the contents of a raw dynamically allocated
uint8_t
array into a vector (which is guaranteed to be empty whenever this scenario happens).vector<uint8_t> myVector; const uint8_t* myRawArray;
It is really important to me that the copy operation is as efficient as possible and portable (various compiler versions might be used).
One approach I thought of using is this:
myVector.reserve(byteCount); myVector.insert(myVector.begin(), myRawArray, myRawArray + byteCount);
Any ideas on how the speed of that compares to this one:
myVector.resize(byteCount); memcpy(myVector.data(), myRawArray, byteCount);
I guess
memcpy
should be fast but then I am forced to useresize
which needs to zero-out the memory, so I guess it will slow it down a bit..Also, any other suggestions?
-
Ryan McCleary over 8 years@M.M: I wasn't aware that std::vector's range constructor zero-initializes the vector's elements. What is the rationale behind this?