2

What's the most efficient way to set the data from a std::vector to a std::valarray? Say we have std::valarray<double> my_valarray; and std::vector<double> my_vector; and we want to copy the data across from my_vector to my_valarray:

Option 1 (using valarray constructor and copy assignment):

my_valarray = std::valarray(my_vector.data(), my_vector.size());

Option 2 (resizing and copying):

my_valarray.resize(my_vector.size());
std::copy(my_vector.begin(), my_vector.end(), std::begin(my_valarray));    

The question arises because in both cases it looks like the complexity is O(2n). In the first case the data is copied to temporary valarray during construction (one allocation + one pass to copy the data) and then on assignment to the final object (one allocation + one pass to copy the data). In the second case there is one allocation + one pass for initialisation of all elements to zero and another pass to copy the data. Do the move semantic of C++11 applies in the first case making it require only one allocation and one pass to copy the data?

Darien Pardinas
  • 5,910
  • 1
  • 41
  • 48

2 Answers2

3

Yes, move semantics applies in the first case, because std::valarray(my_vector.data(), my_vector.size()) is an rvalue and a move assigment operator is defined for the valarray class(http://en.cppreference.com/w/cpp/numeric/valarray/operator%3D).

kraskevich
  • 18,368
  • 4
  • 33
  • 45
  • 2
    We know that. The problem is that every element in [`my_vector.data()`, `my_vector.data() + my_vector.size()`) is copied. – Columbo Jan 04 '15 at 12:14
1

The first option is more efficient. The reason is that std::valarray::resize zero-initializes all data. But i would assume that any compiler worth it's salt would optimize that redundant zero-initialization away.

You can't prevent copying from the vector to the valarray, there is no way to transfer the ownership of the memory block from my_vector to my_valarray.

Stefan
  • 1,539
  • 13
  • 11