Given a C++ vector (let's say it's of doubles, and let's call it unsorted
), what is the most performant way to create a new vector sorted
which contains a sorted copy of unsorted
?
Consider the following naïve solution:
std::vector<double> sorted = unsorted;
std::sort(sorted.begin(), sorted.end());
This solution has two steps:
- Create an entire copy of
unsorted
. - Sort it.
However, there is potentially a lot of wasted effort in the initial copy of step 1, particularly for a large vector that is (for example) already mostly sorted.
Were I writing this code by hand, I could combine the first pass of my sorting algorithm with step 1, by having the first pass read the values from the unsorted
vector while writing them, partially sorted as necessary, into sorted
. Depending on the algorithm, subsequent steps might then work just with the data in sorted
.
Is there a way to do such a thing with the C++ standard library, Boost, or a third-party cross-platform library?
One important point would be to ensure that the memory for the sorted
C++ vector isn't needlessly initialized to zeroes before the sorting begins. Many sorting algorithms would require immediate random-write access to the sorted
vector, so using reserve()
and push_back()
won't work for that first pass, yet resize()
would waste time initializing the vector.
Edit: As the answers and comments don't necessarily see why the "naïve solution" is inefficient, consider the case where the unsorted
array is in fact already in sorted order (or just needs a single swap to become sorted). In that case, regardless of the sort algorithm, with the naïve solution every value will need to be read at least twice--once while copying, and once while sorting. But with a copy-while-sorting solution, the number of reads could potentially be halved, and thus the performance approximately doubled. A similar situation arises, regardless of the data in unsorted
, when using sorting algorithms that are more performant than std::sort
(which may be O(n) rather than O(n log n)).
std::vector
has an efficient copy method. – Fulllengthinsertion_sort
method is added in the STL so that this task can be done in a nice way. – Matteostd::reference_wrapper
s. – Purgative