Тестирование / Профилирование функции хеширования для javas hashmap - PullRequest
2 голосов
/ 23 апреля 2011

Как мне протестировать / профилировать реализацию hashCode () в Java? то есть распределяет ли мои данные испытаний достаточно равномерно и т. д.? Есть ли какой-нибудь простой грубый способ в самом java API?

Ответы [ 2 ]

3 голосов
/ 23 апреля 2011
Map<Integer, Integer> hashCodes = new HashMap<Integer, Integer>();
for (YourHashcodedClass testData: largeCollectionOfTestData) {
    Integer hashCode = Integer.valueOf(testData.hashCode());
    Integer occurrences = hashCodes.get(hashCode);
    if (occurrences == null) {
        occurrences = 0;
    }
    hashCodes.put(hashCode, occurrences+1);
}

Затем проанализируйте свою карту на предмет столкновений.

2 голосов
/ 23 апреля 2011

Честно говоря, вам не нужно профилировать или тестировать распространение вашего hashCode() метода, если вы следуете передовым методам.См. Рецепт хеш-кода ниже от Effective Java .Более того, даже если вы не пишете это слишком хорошо, реализация HashMap повторно обрабатывает ваш результат для уменьшения коллизий:

static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}

Вы также можете использовать HashCodeBuilder из Apache Commons Lang создаст для вас хеш-код.

Эффективный рецепт хеш-кода Java 2nd Edition

  • Сохраните некоторое постоянное ненулевое значение, скажем, 17в переменной int с именем result.
  • Вычислить int хеш-код c для каждого поля:
    • Если поле имеет значение boolean, вычислить (f ? 1 : 0)
    • Если поле равно byte, char, short, int, вычислить (int) f
    • Если поле равно long, вычислить (int) (f ^ (f >>> 32))
    • Если поле имеет значение float, вычислить Float.floatToIntBits(f)
    • Если поле имеет значение double, вычислить Double.doubleToLongBits(f), а затем хэшировать результирующий long, как указано выше.
    • Если поле является объектомreference и метод equals этого класса сравнивает поле путем рекурсивного вызова equals, рекурсивного вызова hashCode для поля.Если значение поля null, вернуть 0.
    • Если поле является массивом, обрабатывать его так, как если бы каждый элемент был отдельным полем.Если каждый элемент в поле массива является значимым, вы можете использовать один из методов Arrays.hashCode, добавленных в выпуске 1.5.
  • Объединить хэш-код c в result следующим образом:result = 31 * result + c;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...