Re[4]: посоветуйте хеш-функцию от указателя
От: watch-maker  
Дата: 01.02.13 14:42
Оценка:
Здравствуйте, pepsicoca, Вы писали:

P>>>>Посоветуйте, какую хэш-функцию лучше взять, чтобы было быстро и переносимо.

WM>>>Кастуй указатель к uintptr_t, и возвращай это значение.

P>>Кстати это мысль. В типичном случае платформы х86 при выделении памяти в куче указатели отличаются в младших разрядах.

В типичной x86 у почти всех адресов структур в младшем бите стоит 0. И в следующем бите тоже. Не ноль там только в разных указателях на упакованные структур, да в указателях на подстроки.

WM>>>Если тебе известно, что от хэш-функции чаще используются младшие биты, то можно сдвинуть (циклически или даже просто так) результат вправо на число бит, равное логарифму типичного выравнивания при выделении памяти (скорее всего будет равно чему-то вроде 2-х или 3-х бит).


P>>Зачем вправо?

P>>Вправо сдвинуть значит потерять различия в близкорасположеных указателях. Как раз тогда и будет плохое распределение, все хеш-значения будут одинаковыми.
P>>Может влево?

P>А, понял почему. При суммировании может и неважно, а при приведении к типу uintptr_t может помочь.

P>Но переносимо никак не узнать, какой шаг выравнивания на данной платформе.
И не нужно. Во-первых, log₂ sizeof int даст хорошее приближение. Во-вторых, циклический сдвиг гарантирует, что мы не потерям информацию, даже если слегка ошибёмся. В-третьих, можно получить нужные параметры и извне. Ну и в-четвёртых, читай следующую строчку:
WM>>>Ну или можно дальше вокруг значения типа uintptr_t сделать этап обычного целочисленного хэширования.
Целочисленное хэширование как раз размазывает все биты, и работает вполне универсально. Просто обычно без него можно обойтись. Но если хочется гарантий, то задействуй его — это не дорого.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.