Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fastest way to convert a std::vector to another std::vector

Tags:

What is the fastest way (if there is any other) to convert a std::vector from one datatype to another (with the idea to save space)? For example:

std::vector<unsigned short> ----> std::vector<bool>  

we obviously assume that the first vector only contains 0s and 1s. Copying element by element is highly inefficient in case of a really large vector.

Conditional question: If you think there is no way to do it faster, is there a complex datatype which actually allows fast conversion from one datatype to another?

like image 901
scigor Avatar asked Oct 26 '11 07:10

scigor


People also ask

Is std::vector fast?

A std::vector can never be faster than an array, as it has (a pointer to the first element of) an array as one of its data members. But the difference in run-time speed is slim and absent in any non-trivial program. One reason for this myth to persist, are examples that compare raw arrays with mis-used std::vectors.

Is STD array faster than std::vector?

Difference between std::vector and std::array in C++ As array is fixed size, once initialized can't be resized. Vector occupies more memory. Array is memory efficient data structure. Vector takes more time in accessing elements.

How do I copy a vector array to another?

Begin Initialize a vector v1 with its elements. Declare another vector v2 and copying elements of first vector to second vector using constructor method and they are deeply copied. Print the elements of v1. Print the elements of v2.


1 Answers

std::vector<bool>  

Stop.

A std::vector<bool> is... not. std::vector has a specialization for the use of the type bool, which causes certain changes in the vector. Namely, it stops acting like a std::vector.

There are certain things that the standard guarantees you can do with a std::vector. And vector<bool> violates those guarantees. So you should be very careful about using them.

Anyway, I'm going to pretend you said vector<int> instead of vector<bool>, as the latter really complicates things.

Copying element by element is highly inefficient in case of a really large vector.

Only if you do it wrong.

Vector casting of the type you want needs to be done carefully to be efficient.

If the the source T type is convertible to the destination T, then this is works just fine:

vector<Tnew> vec_new(vec_old.begin(), vec_old.end()); 

Decent implementations should recognize when they've been given random-access iterators and optimize the memory allocation and loop appropriately.

The biggest problem for non-convertible types you'll have for simple types is not doing this:

std::vector<int> newVec(oldVec.size()); 

That's bad. That will allocate a buffer of the proper size, but it will also fill it with data. Namely, default-constructed ints (int()).

Instead, you should do this:

std::vector<int> newVec; newVec.reserve(oldVec.size()); 

This reserves capacity equal to the original vector, but it also ensures that no default construction takes place. You can now push_back to your hearts content, knowing that you will never cause reallocation in your new vector.

From there, you can just loop over each entry in the old vector, doing the conversion as needed.

like image 86
Nicol Bolas Avatar answered Sep 19 '22 15:09

Nicol Bolas