Я переделал профилирование Нейта Коля и получил разные результаты. В моем тестовом примере прямая сортировка вектора всегда более эффективна, чем использование набора. Я добавил новый, более эффективный метод, используя unordered_set
.
Имейте в виду, что метод unordered_set
работает только в том случае, если у вас есть хорошая хеш-функция для типа, который вам нужен, uniqued и отсортирован. Для малышей это просто! (Стандартная библиотека предоставляет хэш по умолчанию, который является просто функцией идентификации.) Кроме того, не забудьте отсортировать в конце, поскольку unordered_set, ну, в общем, неупорядоченный:)
Я немного покопался в реализации set
и unordered_set
и обнаружил, что конструктор фактически создает новый узел для каждого элемента, прежде чем проверять его значение, чтобы определить, должен ли он быть вставлен (в реализации Visual Studio, в как минимум).
Вот 5 методов:
f1: просто с помощью vector
, sort
+ unique
sort( vec.begin(), vec.end() );
vec.erase( unique( vec.begin(), vec.end() ), vec.end() );
f2: преобразовать в set
(используя конструктор)
set<int> s( vec.begin(), vec.end() );
vec.assign( s.begin(), s.end() );
f3: преобразовать в set
(вручную)
set<int> s;
for (int i : vec)
s.insert(i);
vec.assign( s.begin(), s.end() );
f4: преобразовать в unordered_set
(используя конструктор)
unordered_set<int> s( vec.begin(), vec.end() );
vec.assign( s.begin(), s.end() );
sort( vec.begin(), vec.end() );
f5: преобразовать в unordered_set
(вручную)
unordered_set<int> s;
for (int i : vec)
s.insert(i);
vec.assign( s.begin(), s.end() );
sort( vec.begin(), vec.end() );
Я провел тест с вектором из 100 000 000 вставок, выбранным случайным образом в диапазонах [1,10], [1 000] и [1 100 000]
Результаты (в секундах, чем меньше, тем лучше):
range f1 f2 f3 f4 f5
[1,10] 1.6821 7.6804 2.8232 6.2634 0.7980
[1,1000] 5.0773 13.3658 8.2235 7.6884 1.9861
[1,100000] 8.7955 32.1148 26.5485 13.3278 3.9822