В некотором библиотечном коде у меня есть Список, который может содержать 50 000 элементов или больше.
Вызывающие библиотеки могут вызывать методы, которые приводят к добавлению строк в список. Как я могу эффективно проверить уникальность добавляемых строк?
В настоящее время, перед добавлением строки, я просматриваю весь список и сравниваю каждую строку с добавленной строкой. Это начинает показывать масштабные проблемы, превышающие 10 000 предметов.
Я сравню это, но интересуюсь проницательностью.
- Если я заменил List < > на словарь < > , будет ContainsKey() заметно быстрее, так как список увеличится до 10 000 элементов и далее?
- Если я отложил проверку уникальности до тех пор, пока не будут добавлены все элементы, будет ли она быстрее? В этот момент мне нужно будет проверить каждый элемент на каждый другой элемент, все еще выполняющий операцию n ^^ 2.
ИЗМЕНИТЬ
Некоторые базовые результаты. Я создал абстрактный класс, который предоставляет 2 метода: Fill and Scan. Заполнение только заполняет коллекцию n элементами (я использовал 50 000). Сканирование просматривает список m раз (я использовал 5000), чтобы увидеть, присутствует ли данное значение. Затем я построил реализацию этого класса для List, а другой для HashSet.
Используемые строки были равномерно длиной 11 символов и случайным образом сгенерированы методом абстрактного класса.
Очень простой микро-бенчмарк.
Hello from Cheeso.Tests.ListTester
filling 50000 items...
scanning 5000 items...
Time to fill: 00:00:00.4428266
Time to scan: 00:00:13.0291180
Hello from Cheeso.Tests.HashSetTester
filling 50000 items...
scanning 5000 items...
Time to fill: 00:00:00.3797751
Time to scan: 00:00:00.4364431
Итак, для строк этой длины HashSet примерно на 25 раз быстрее, чем List, при сканировании на уникальность. Кроме того, для такого размера коллекции HashSet имеет нулевое наказание за List при добавлении элементов в коллекцию.
Результаты интересны и недействительны. Чтобы получить достоверные результаты, мне нужно будет делать интервалы прогрева, несколько испытаний, со случайным выбором реализации. Но я уверен, что это слегка сдвинет планку.
Спасибо всем.
EDIT2
После добавления рандомизации и многопроцессорных испытаний, HashSet последовательно превосходит List в этом случае примерно на 20x.
Эти результаты не обязательно выполняются для строк переменной длины, более сложных объектов или разных размеров коллекции.