В настоящее время я использую MS VC ++ 2008 с поставляемой стандартной библиотекой с расширениями.
Я хочу использовать хешированные контейнеры для быстрой вставки / удаления / поиска объектов. Поэтому я подумал, что это должно работать просто замечательно:
stdext::hash_set<MyOjbectClass*>
Я обнаружил, что коллизии очень высоки с хэш-функцией по умолчанию (которая, я полагаю, просто использует значение указателя).
Когда я запускаю следующий код в отладчике:
stdext::hash_set<void*> hs;
for (int i=0; i<30; i++)
{
hs.insert(new std::string());
}
Я вижу, что ВСЕ предметы были помещены в одно ведро! (Facepalm)
Хотя все указатели уникальны. Так что я могу забыть о O (1).
Итак, как правильно заставить его работать эффективно?
Предоставить собственную хэш-функцию? Что хорошо с такими указателями?
Примечание: мне нужно использовать hash_map / hash_set. Пожалуйста, не предлагайте использовать unordered_map / set или boost и т. Д.
Немного поискав, я нашел несколько хешей. Следующие ресурсы были полезны:
2 функции найдены здесь: Какова наилучшая хэш-функция для ключей uint64_t в диапазоне от 0 до максимального значения?
и 1 функция здесь: http://naml.us/blog/2012/03
После некоторого тестирования MurmurHash3 показал лучшие результаты для меня. Это лучшая производительность. Стандартное отклонение распределения сегментов почти одинаково для всех трех хеш-функций и намного лучше, чем в случае использования стандартной хеш-функции.
Других решений пока нет …