У меня есть собственный класс с закрытым хэш-сетом / открытой адресацией (т.е. без связанных списков).Он очень специфичен для моих нужд - он не является общим (только для положительных длинных чисел), требует предопределенного количества вставляемых записей и не поддерживает удаление - но он должен занимать как можно меньше места..
Поскольку у него так мало функциональных возможностей, это действительно маленький и простой класс.Однако по какой-то причине, когда я вставляю много записей, число коллизий становится слишком большим, слишком быстрым.
Некоторый код (Java):
public class MyHashSet
{
private long[] _entries;
public MyHashSet(int numOfEntries)
{
int neededSize = (int)(numOfEntries / 0.65D);
_entries = new long[neededSize];
}
public void add(long num)
{
int cell = ((Long) (num % _entries.length)).intValue();
while (_entries[cell] != 0)
{
if (++cell >= _entries.length)
cell = 0;
}
_entries[cell] = num;
}
...
У меня есть главный, который создаетобъект MyHashSet с 10 миллионами в качестве параметра, затем вызывает add () 10 миллионов раз с другим случайно сгенерированным (но положительным) длинным числом.В то время как на обычном Java HashSet эта вставка в целом занимает около секунды, для завершения с MyHashSet требуется около 13 секунд.Я добавил счетчик для коллизий, и, действительно, количество коллизий составляет 3-6 миллиардов - намного больше, чем ожидалось (я предполагаю, что около 30-40 миллионов ожидается).
Я что-то не так делаю?Что-то не так с самим хэшированием?Почему так много коллизий, и что я могу с этим поделать?
Спасибо!
PS: число 0,65 в коде означает, что таблица заполнится только на 65%,который я знаю, должен хорошо работать в закрытых хэш-сетах.В связи с этим, даже если я установлю его на 20%, вставка по-прежнему занимает> 10 секунд.
- РЕДАКТИРОВАТЬ -
Это довольно неудобно, но мой тестовый кодвоссоздайте объект Random (с System.currentTimeMillis () в качестве начального числа) в каждой итерации цикла, а не используйте один и тот же для всего цикла ..
После исправления требуется около 2-3секунд для вставки.Это все еще кажется слишком большим для сравнения - почему java HashSet по умолчанию вставляется в секунду, когда он более «сложен», чем MyHashSet?Я сейчас получаю около 9 миллионов столкновений.Я также попытался снять код регистрации, чтобы посмотреть, поможет ли он, но это все равно не поможет.Буду признателен за любые идеи и еще раз прошу прощения за путаницу.