Hashtable медленно добавляет значения?

В настоящее время я использую Hashtable для хранения списка уникальных идентификаторов и связанных данных, все из которых считываются из файла.

Длина этого файла данных может быть очень большой, от 1 записи до нескольких сотен тысяч. Я заметил значительное замедление скорости добавления записей в хеш-таблицу после того, как она превысила 50 000 записей.

Я думаю, что установка начальной емкости может помочь, но, очевидно, я не могу знать это число, так как данные считываются из файла. Может ли кто-нибудь предложить способ ускорить добавление большого количества записей, или это нормальное поведение?

edit: Сейчас я просто использую Hashtable. Я думаю, что это, вероятно, должно быть Dictionary‹string, MyDataObject>, но это похоже на отдельную проблему.


person We Are All Monica    schedule 04.09.2009    source источник
comment
Какой класс вы используете? Словарь‹TKey, TValue›?   -  person Daniel Brückner    schedule 04.09.2009
comment
Проверяли ли вы, повышает ли установка большой емкости производительность при вставке большого количества элементов?   -  person AnthonyWJones    schedule 04.09.2009
comment
Настройка емкости не должна иметь большого значения — и ее не следует делать, если вы не знаете, сколько записей у вас будет (например, от 1 до 100 000+).   -  person tanascius    schedule 04.09.2009
comment
Я не проверял, но согласен с Танаскиусом - я не хочу устанавливать емкость 100 000, если у меня будет только ‹10 предметов.   -  person We Are All Monica    schedule 04.09.2009
comment
Вы читаете файл в память, прежде чем вставить его в словарь? Пожалуйста, сделайте это (в целях тестирования), чтобы убедиться, что проблема действительно во вставке.   -  person tanascius    schedule 04.09.2009
comment
В настоящее время я этого не делаю, но я профилировал код, и узким местом определенно является Hashtable.Add().   -  person We Are All Monica    schedule 04.09.2009
comment
Обычно емкость увеличивается в несколько раз (например, в 1,5 раза), поэтому, если емкость, равная 50 000, становится слишком маленькой, она будет скорректирована до 75 000.   -  person tanascius    schedule 04.09.2009
comment
Я только что протестировал Dictionary‹Int32, Int32› и вставил числа от 1 до 1.000.000. Средняя вставка занимала чуть меньше 100 наносекунд на довольно медленном рабочем столе, и я мог наблюдать только небольшие колебания скорости вставки, менее чем в два раза, вероятно, вызванные изменением размера резервного хранилища.   -  person Daniel Brückner    schedule 04.09.2009
comment
Я думаю, мне нужно сделать что-то другое, кроме поведения роста по умолчанию. Я не вижу способа изменить этот фактор в документации - это правильно?   -  person We Are All Monica    schedule 04.09.2009
comment
Не концентрируйтесь на факторе роста или на процессе выращивания вообще. Словарь рабочий, на 50 000 статей и многое другое... Взгляните на окружающий код, даже если вы профилировали.   -  person tanascius    schedule 04.09.2009
comment
Теперь я переключился на использование Hashtable и получил чуть более 1300 наносекунд на вставку в диапазоне от 1 до 1 000 000 — это в 13 раз медленнее. Итак, мое первое предложение: используйте или хотя бы протестируйте Dictionary‹TKey, TValue› и получите сильную печать бесплатно. Вставка только значений от 1 до 10 000 дала среднее время вставки около 350 наносекунд. Таким образом, я могу подтвердить замедление от 3 до 4 (используя очень ненаучный код профилирования).   -  person Daniel Brückner    schedule 04.09.2009


Ответы (1)


см. здесь сравнение хеш-таблиц и словарей для большого количества элементов.

person Preet Sangha    schedule 04.09.2009
comment
Я не думал, что разница будет такой радикальной - похоже, что переход на словарь поможет решить мою проблему. Тем не менее, я не могу проверить прямо сейчас, но я подозреваю, что увижу такое же замедление в меньшем масштабе со словарем. - person We Are All Monica; 04.09.2009
comment
Сравнение, тем не менее, интересное, потому что тестируется с 10 000 000 ключей и графическим интерфейсом в качестве идентификатора. Это занимает ~ 6 секунд. Так что узкого места на 50 000 записей быть не должно... Вот поэтому я и думаю, что дело может быть в файле, а не вставке... - person tanascius; 04.09.2009
comment
Этот эталонный тест не очень хорош, потому что новые GUID генерируются внутри временного цикла, а генерация GUID медленнее по сравнению с доступом к хеш-таблице. В ходе быстрого теста я обнаружил, что создание нового GUID занимает примерно в 6 раз больше времени, чем вставка в Dictionary‹Int32, Guid›. - person Daniel Brückner; 04.09.2009
comment
Хорошо, это проблема, но не в этом контексте. Вставка 10 000 000 записей за 6 секунд. с созданием дополнительного GUID во время измерения времени выполняется быстро и не должно создавать узких мест. - person tanascius; 04.09.2009