Мне нужна высокопроизводительная функция хеширования строк в python, которая выдает целые числа с выходными данными не менее 34 (64 бита имеет смысл, но 32 - это слишком мало).Есть несколько других вопросов, таких как этот, о переполнении стека, но из всех принятых / одобренных ответов, которые я смог найти, попал в одну из нескольких категорий, которые не применимы (по указанной причине).
- Используйте встроенную функцию
hash()
. Эта функция, по крайней мере, на машине, для которой я разрабатываю (с Python 2.7 и 64-битным процессором), выдает целое число, которое вписывается в32 бита - недостаточно для моих целей. - Использовать hashlib. hashlib предоставляет криптографические процедуры хеширования, которые на намного медленнее, чем они должны быть для не криптографическихцели.Я нахожу это само собой разумеющимся, но если вам нужны тесты и цитаты, чтобы убедить вас в этом факте, тогда я могу предоставить это.
- Используйте функцию
string.__hash__()
в качестве прототипа для написания вашей собственной функции. Я подозреваю, что это будет правильный путь, за исключением того, что эффективность этой конкретной функции заключается в использовании функции c_mul, которая охватывает 32 бита - опять же, слишком мало для моего использования!Очень расстраивает, это так близко к идеалу!
Идеальное решение будет иметь следующие свойства в относительном, беспорядочном порядке важности.
- Имеет выходной диапазон, расширяющийсядлина не менее 34 бит, вероятно 64 бит, при этом сохраняются согласованные лавинные свойства более всех бит.(Конкатенация 32-битных хэшей имеет тенденцию нарушать свойства лавины, по крайней мере, с моими тупыми примерами.)
- Portable.Учитывая одну и ту же строку ввода на двух разных машинах, я должен получить один и тот же результат оба раза.Эти значения будут сохранены в файле для последующего повторного использования.
- Высокая производительность.Чем быстрее, тем лучше, так как эта функция будет вызываться примерно 20 миллиардов раз во время выполнения программы, которую я запускаю (сейчас это критичный для производительности код). Ее не нужно писать на C, это действительнопросто нужно превзойти md5 (где-то в области встроенного хеша () для строк).
- Принимать целое число «возмущение» (какое слово лучше использовать здесь?) в качестве ввода для изменения вывода,Я привел пример ниже (правила форматирования списка не позволили бы мне разместить его ближе.) Я полагаю, что это не на 100% необходимо, так как его можно смоделировать, нарушив вывод функции вручную, но имея его в качестве входных данных, я получаюприятное теплое чувство.
- Написано полностью на Python.Если это абсолютно положительно, нужно написать для написания на C, тогда я думаю, что это можно сделать, но я бы взял на 20% более медленную функцию, написанную на python, по сравнению с более быстрой в C, просто из-за координации проектаголовная боль от использования двух разных языков.Да, это отговорка, но здесь приведен список пожеланий.
Пример 'возмущенного' хеша, где значение хеша радикально изменяется небольшим целочисленным значением n
def perturb_hash(key,n):
return hash((key,n))
Наконец, если вам интересно, что, черт возьми, я делаю, что мне нужна такая специфическая хеш-функция, я делаю полную переписывание модуля pybloom, чтобы значительно повысить его производительность.Мне это удалось (теперь он работает примерно в 4 раза быстрее и занимает около 50% пространства), но я заметил, что иногда, если фильтр становился достаточно большим, он внезапно вносил ложные срабатывания.Я понял, что это потому, что хэш-функция не адресовала достаточно битов.32 бита могут адресовать только 4 миллиарда бит (учтите, что фильтр адресует биты, а не байты), а некоторые из фильтров, которые я использую для геномных данных, удваивают это или более (следовательно, минимум 34 бита).
Спасибо!