I have a routine in which I define a bunch of objects (around 20), call them Jet
, which have a defined <
that I'm using to sort them. After they are sorted, I take the lowest two. What is a fast way to do this? The options I've thought of so far:
boost::ptr_vector<Jet>
use the built in .sort()
, take the first two, boost::ptr_list<Jet>
, use .sort()
, take the first two max_element
, remove the element, and run again. I assume using std::vector<Jet>
would be the worst option because: I don't need random access; the sort will move objects around in memory; and the objects will be copied when calling push_back(Jet)
. Because of the copying required, I'd also assume that an std::list<Jet>
would be worse than boost::ptr_list<Jet>
. I'd further assume that taking max_element
twice would be faster than sorting the whole list.
Is my logic sound? Is the performance difference going to be significant? Is there some other option I'm not thinking of?
There is a standard library algorithm to do exactly this:
std::vector<Jet> v;
// populate v
std::partial_sort(v.begin(), v.begin() + 2, v.end());
v[0]
is now the smallest element and v[1]
is now the second smallest element; remaining elements are in an unspecified order. std::vector<>
can be substituted with std::deque<>
, as the latter also has random-access iterators.
(Note that the complexity mentioned on the page I linked to is incorrect; C++11 §25.4.1.3 says the complexity is (last - first) * log(middle - first)
.)