Алгоритмы общего назначения
Простые хэш-функции высокой производительности
Уже знакомы с первым выпуском? Таки второй вышел!
Прежде всего проведем небольшой независимый тест хэш-функций общего назначения. Все эти функции, по-определению, имеют очень простую и понятную структуру, основаны на простых операциях и применяются довольно широко.
Что отличает проведенный мною тест? Здесь с целью получения достоверных и стабилных результатов выполняется несколько паетных тесирований на совершенно разных наборах данных. При этом каждое тестирование включает несколько подтестов, каждый из котторых в определенной степени отличается по сложности тестового материала.
Зачем все это? Да, как правило, распространены либо сугубо статистические тесты, методика которых схожа с методикой тестирования генераторов псевдослучайных чисел и поточных шифров, либо тесты на одном наборе информации. Но говорить о хэш-функции как о хорошей сложно, исходя из одного теста. Более того, такую функцию можно просто оптимизировать под определенный набор данных, строки определенной длины или в определенном промежутке символов. Один тест может не выявить слабые места алгоритма. Здесь же вы найдете комплексное и мощное тестирование на богатом наборе тестового материала. Все это, возможно, приведет к самым неожиданным результатам.
Приступим к тестированию.
Тестовый набор содержит слова, отсортированные в алфавитном порядке, дубликаты удалены. В качестве основы были взяты заголовки из Русской Википедии, Большой советской энциклопедии, Большого англо-русского словаря и других словарных источников в общем колличестве 2726299 уникальных слова.
Важно отменить, что все тексты - в кодировке cp866, минимальная длина - 3 символа, регистр - верхний. Тестовый набор можно скачать здесь или здесь. Инструментарий тестирования, который включает исходные тексты всех алгоритмов, можно найти здесь. Результаты тестов в виде электронной таблицы можно найти здесь.
Порядок тестово таков: хэшируем все слова в текстовом файле, сортируем результаты, находим коллизии. Чем меньше дубликатов, тем лучше алгоритм хэширования, поскольку идентичных слов в тестовом наборе у нас нет.
Описание вариантов теста:
-
Тест A: простое хэширование
-
Тест B: добавляем символ конца строки к слову
-
Тест C: добавляем четыре символа конца строки к слову
- Тест D: добавляем к слову пять символов ABCDE
- Тест E: добавляем к слову его дубликат
- Тест F: добавляем к слову его три дубликата
- Тест G: изменяем порядок символов в слове на обратный
- Тест H: делаем из слова его палиндром
Тест A - простой, здесь хэшируются только слова. Проблемы могут быть только у функций, которые “сыпятся” на коротких словах.
Тест B - небольшая разминка перед сложной проверкой. Добавляем гарантированное совпадение в конец и ждем коллизий.
Тест C - весьма экстримальный, поскольку здесь мы встречаем последовательное повторение одного символа, которая может ударить по лавинному эффекту.
Тест D - тоже не прост, у каждого слова теперь гарантировано 5 совпадений. Только качественная функция здесь не даст значительно больше коллизий.
Тест E - самый сложный для прохождения. Как правило, здесь почти все показывают результаты немного хуже или даже дают всплеск столкновений.
Тест F - аналогично предыдущему тесту очень сложен, однако результаты могут быть несколько лучше ввиду большего количества итераций
Тест G - это проверка корректности первого теста на стабильность результатов. В этом тесте участвуют неосмыссленные слова, хотя набор символов идентичен
Тест H -
это проверка логики алгоритма. Использование одного текста в прямом и обратном порядке не должно снизить лавинный эффект и вызвать увеличение числа столкновений.
Функции семейства MaHash были разработаны специально для данного теста, остальные участники вступили в схватку без подготовки. В процессе тестирования были разработаны модификации некоторых популярных алгоритмов, которые показали результаты лучших оригинальных.
MaHash7
Что отличает эту функцию? Правильно, бросается в глаза таблица замены (подстановки). Зачем она в таком простом алгоритме? Прежде всего затем, что таблица замены - это сложная функция, которую просто описали несколько иным способом. При этом такую функцию очень легко реализовать как программно, так и аппаратно, скорость запроса к таблице высока в обоих случаях. У функции есть параметр - число итераций. Статистически, лучшим параметром будет одна итерация для большинства текстов. Хотя для оригинальной функции оптимальными будут три итерации. Сама таблица подстановки идентична таковой в криптоалгоритме Skipjack. Результаты не лучшие, но конструкция имеет право на жизнь.
static const unsigned char sTable[256] =
{
0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9,
0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28,
0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53,
0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2,
0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8,
0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90,
0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76,
0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d,
0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18,
0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4,
0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40,
0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5,
0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2,
0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8,
0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac,
0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46
};
#define LROT14(x) (((x) << 14) | ((x) >> 18 ))
#define ITERATIONS 1
unsigned int
MaHash7 (unsigned char *str, unsigned int len)
{
unsigned int hash = len, i;
for (i = 0; i != len * ITERATIONS; i++)
{
str += (i % len);
hash =
LROT13 (hash + ((hash << 8) ^ (hash >> 12))) -
sTable[(*str + i) & 255];
}
return hash;
}
MaHash9
Что изменено? Другие константы сдвигов и циклический сдвиг влево на 14 бит, дополнительная операция побитового НЕ. Как результат - немного лучше показатели в ряде тестов, но в итоге изменения себя не оправдали. В итоге - далеко не первое место, так же - твердый середнячок.
#define LROT14(x) (((x) << 14) | ((x) >> 18 ))
unsigned int MaHash9 (unsigned char *str, unsigned int len)
{
unsigned int hash = len, i;
for (i = 0; i != len; i++, str++)
{
hash = LROT14( ~hash + ((hash << 6) ^ (hash >> 11))) - sTable[(*str + i) & 255];
}
return hash;
}
MaHash2
Что же здесь нового? По-сути, это два алгоритма MaHash для параллельного подсчета двух 32-разрядных значений. На каждом этапе результат вычисления оригинальной и видоизмененной функции с обратным циклическим сдвигом вправо взаимозаменяются. Результатом хэш-функции будет сумма подфункций по модулю 2 (операция XOR). Такая конструкция позволила улучшить результаты алгоритма в плане числа коллизий. Достоинства алгоритма - отсутствие операций деления, умножения (наиболее медленных на современных неспециализированных процессорах) и возможность распараллеливания. С неба звезд не хватает, но показывает сравнительно хорошие результаты - восьмое место в рейтинге с небольшим отставанием от ближайших соперников.
#define LROT(x) (((x) << 11) | ((x) >> 21 ))
#define RROT(x) (((x) << 21) | ((x) >> 11 ))
unsigned int MaHash2 (unsigned char *str, unsigned int len)
{
unsigned int t, hash1 = len, hash2 = len, i;
for (i = 0; i != len; i++, str++)
{
hash1 += sTable[(*str + i) & 255];
hash1 = LROT(hash1 + ((hash1 << 6) ^ (hash1 >> 8)));
hash2 += sTable[(*str + i) & 255];
hash2 = RROT(hash2 + ((hash2 << 6) ^ (hash2 >> 8)));
t = hash1;
hash1 = hash2;
hash2 = t;
}
return hash1 ^ hash2;
}
MaHash8
Найдем отличия? Изменились сдвиги, циклический сдвиг увеличился не несколько разрядов. На смену взаимозамены результатов подфункций теперь они “собираются” из младшего родного слова и старшего слова альтернативной функции. Показал в среднем лучшие среди участников результаты.
#define LROT14(x) (((x) << 14) | ((x) >> 18 ))
#define RROT14(x) (((x) << 18) | ((x) >> 14 ))
unsigned int MaHash8 (unsigned char *str, unsigned int len)
{
unsigned int sh1, sh2, hash1 = len, hash2 = len, i;
for (i = 0; i != len; i++, str++)
{
hash1 += sTable[(*str + i) & 255];
hash1 = LROT14(hash1 + ((hash1 << 6) ^ (hash1 >> 11)));
hash2 += sTable[(*str + i) & 255];
hash2 = RROT14(hash2 + ((hash2 << 6) ^ (hash2 >> 11)));
sh1 = hash1;
sh2 = hash2;
hash1 = ((sh1 >> 16) & 0xffff) | (sh2 & 0xffff) << 16;
hash2 = ((sh2 >> 16) & 0xffff) | (sh1 & 0xffff) << 16;
}
return hash1 ^ hash2;
}
MaHash4
Вернулись обратно? Да, здесь опять классические сдвиги и обычный циклический сдвиг. Только вместо взаимозамены опять “сборка” значений. Эта функция, как и прошлая, стабильно показывает очень хорошие результы, не имеет “провалов”. Не даром заняла второе место в общем зачете и победила в сокращенном тесте.
#define LROT(x) (((x) << 11) | ((x) >> 21 ))
unsigned int
MaHash4 (unsigned char *str, unsigned int len)
{
unsigned int sh1, sh2, hash1 = len, hash2 = len, i;
for (i = 0; i != len; i++, str++)
{
hash1 += sTable[(*str + i) & 255];
hash1 = LROT (hash1 + ((hash1 << 6) ^ (hash1 >> 8)));
hash2 += sTable[(*str + i) & 255];
hash2 = RROT (hash2 + ((hash2 << 6) ^ (hash2 >> 8)));
sh1 = hash1;
sh2 = hash2;
hash1 = ((sh1 >> 16) & 0xffff) | (sh2 & 0xffff) << 16;
hash2 = ((sh2 >> 16) & 0xffff) | (sh1 & 0xffff) << 16;
}
return hash1 ^ hash2;
}
MaHash5
Усложнили? Да, немного. Добавлено дополнительное преобразование в конце шага. Результаты стабильны для обоих тестов, хотя в сравнении с прошлой функцией усложнение, которое немного улучшило результат первого теста, не оправдано. Как результат, пятое место в зачете и фактическая несостоятельность.
#define LROT(x) (((x) << 11) | ((x) >> 21 ))
unsigned int
MaHash5 (unsigned char *str, unsigned int len)
{
unsigned int sh1, sh2, hash1 = len, hash2 = len, i;
for (i = 0; i != len; i++, str++)
{
hash1 += sTable[(*str + i) & 255];
hash1 = LROT (hash1 + ((hash1 << 6) ^ (hash1 >> 8)));
hash2 += sTable[(*str + i) & 255];
hash2 = RROT (hash2 + ((hash2 << 6) ^ (hash2 >> 8)));
sh1 = LROT (hash1 + ((hash1 << 6) ^ (hash1 >> 8)));
sh2 = RROT (hash2 + ((hash2 << 6) ^ (hash2 >> 8)));
hash1 = ((sh1 >> 16) & 0xffff) | (sh2 & 0xffff) << 16;
hash2 = ((sh2 >> 16) & 0xffff) | (sh1 & 0xffff) << 16;
}
return hash1 ^ hash2;
}
MaHash11
Знакомо? Да, ведь это MaHash2 с другими константами сдвигов. Причем, теперь для каждой подфункции теперь применяется свое значение циклического сдвига. Показала себя очень хорошо, без резких счачков коллизий в сложных наборах. Третье место в нашем рейтинге.
#define LROT12(x) (((x) << 12) | ((x) >> 20 ))
#define RROT13(x) (((x) << 19) | ((x) >> 13 ))
unsigned int MaHash11 (unsigned char *str, unsigned int len)
{
unsigned int t, hash1 = len, hash2 = len, i;
for (i = 0; i != len; i++, str++)
{
hash1 += sTable[(*str + i) & 255];
hash1 = LROT12(hash1 + ((hash1 << 6) ^ (hash1 >> 14)));
hash2 += sTable[(*str + i) & 255];
hash2 = RROT13(hash2 + ((hash2 << 6) ^ (hash2 >> 14)));
t = hash1;
hash1 = hash2;
hash2 = t;
}
return hash1 ^ hash2;
}
MaHash10
Что-то новенькое ? Не совсем, но стоит особняком, выделяется немного новой структурой. Здесь уже нет двух параллельных подфункций, хотя и вычисляются два 32-разядных значения на каждом шаге. Как и впрошлой функции, циклические сдвиги различны для каждого вычисления. Как оказалась, такая конструкция имеет небольшие всплески коллизий и от классической пока отсказываться спешить не следует. Из всего семейства показала худший результат, хотя и опередила некоторых именитых соперников.
#define LROT14(x) (((x) << 14) | ((x) >> 18 ))
#define RROT14(x) (((x) << 18) | ((x) >> 14 ))
unsigned int MaHash10 (unsigned char *str, unsigned int len)
{
unsigned int hash1 = len, hash2 = len, i, value;
for (i = 0; i != len; i++, str++)
{
value = sTable[(*str + i) & 255];
hash1 = LROT14(hash2 + ((hash2 << 6) ^ (hash2 >> 11)));
hash1 += value;
hash2 = RROT15(hash1 + ((hash1 << 6) ^ (hash1 >> 11)));
hash2 += value;
}
return hash1 ^ hash2;
}
MaHash3
Опять усложняем ? И не зря. Как показали тесты, функция - одна из самых удачных в семействе. Дополнительная интерация немного снизила число коллизий на самых сложных тестах.
#define LROT(x) (((x) << 11) | ((x) >> 21 ))
#define RROT(x) (((x) << 21) | ((x) >> 11 ))
unsigned int
MaHash3 (unsigned char *str, unsigned int len)
{
unsigned int t, hash1 = len, hash2 = len, i;
unsigned char index;
for (i = 0; i != len; i++, str++)
{
index = (*str + i) & 255;
hash1 += sTable[index];
hash1 = LROT (hash1 + ((hash1 << 6) ^ (hash1 >> 8)));
hash2 += sTable[(sTable[index] + 1) & 255];
hash2 = RROT (hash2 + ((hash2 << 6) ^ (hash2 >> 8)));
t = hash1;
hash1 = hash2;
hash2 = t;
}
hash1 = LROT (hash1 + ((hash1 << 6) ^ (hash1 >> 8)));
hash1 += sTable[len];
hash2 = RROT (hash2 + ((hash2 << 6) ^ (hash2 >> 8)));
hash2 += sTable[len];
return hash1 ^ hash2;
}
MaBKDR
Говорят, существующие алгоритмы не улучшишь? Пусть говорят. У BKDR есть небольшой недостаток, он хорош на строках одной длины - на больших объемах текстов различной длины число коллизий увеличивается. Это легко исправить, просто добавляем счетчик символа на каждом шаге. Такая модификация, как показали исследования, значительно улучшит статистические показатели, снизив число столкновений. В то же время никаких деградаций функции по результатам тестов мной замечено не было. Значит, модификация имеет право на жизнь и такой вариант предпочтительнее оригинальной функции. И, что важно, добавлена лишь одна операция, которая выполняется быстро на современных процессорах.
unsigned int
maBKDRHash (unsigned char *str, unsigned int len)
{
unsigned int seed = 131313; /* 31 131 1313 13131 131313 etc.. */
unsigned int hash = 0;
unsigned int i = 0;
for (i = 0; i < len; str++, i++)
{
hash = (hash * seed) + *str + /* maBKDR modification here*/ i;
}
return hash;
}
MaPrime
Простые числа? Они самые. Существующие простые хэш-функции на простых числах немного деградируют в сложных случаях, судя по моим тестам. Такие случаи - это наборы текстов, имеющие совпадающие участки. Более точно - это потому, что алгоритмы не предусмотрели четкой взаимосвязи между символом и его позицией в строке. Наш алгоритм очень прост, основан на операции умножения на простое число. Используется таблица подстановки, так же что и в других моих функциях. Как вариант, может использоваться упрощенный вариант без таблицы. Преимущества - элементарная и понятная структура, простота реализации и хорошие результаты во всех тестах.
#define PRIME_MULT 0x1FAF
#define START_PRIME 0x3A8F05C5
#define USE_SBOX
unsigned int maPrimeHash (unsigned char *buf, unsigned int len)
{
unsigned int hval = START_PRIME, i;
for (i = 0; i != len; i++, buf++)
{
#ifdef USE_SBOX
hval ^= sTable[(*buf + i) & 255];
#else
hval += ((unsigned int)*buf) ^ i;
#endif
hval *= PRIME_MULT;
}
return hval;
}
MaPrime2c
Брат-близнец? Конечно. И найти отоличия сложно. Этот алгоритм отличается константой, на которую умножается внутреннее состояние, и тем, что его стартовым значением является не фиксированное число, а длина сообщения. Результаты тоже не плохие. По соотношению качества хэширования и производительности это лучшая из моих функций.
#define PRIME_MULT 1717
unsigned int
maPrime2cHash (unsigned char *str, unsigned int len)
{
unsigned int hash = len, i;
for (i = 0; i != len; i++, str++)
{
hash ^= sTable[( *str + i) & 255];
hash = hash * PRIME_MULT;
}
return hash;
}
MaPrime2d
Какой смысл опять усложнять? Он, определенно есть. Как показали автоматизированные тесты, функция показывает более стабильные результаты, нежели оригинальная. Да и дополнения не так сильно отражаются на производительности. Второй момент - это возможность параметризации, т.е. тонкой натройки под определенный набор данных. Существенный параметр здесь - это константа циклического сдвига. В тесте использован сдвиг на два бита вправо, что обеспечило усредненные результаты по тестам вцелом, однако использование некоторых других значений может быть более приемлимым в зависимости от набора текстов. К примеру - один или три бита.
unsigned int
maPrime2dHash (unsigned char *str, unsigned int len)
{
unsigned int hash = 0, i;
unsigned int rotate = 2;
unsigned int seed = 0x1A4E41U;
for (i = 0; i != len; i++, str++)
{
hash += sTable[(*str + i) & 255];
hash = (hash << (32 - rotate) ) | (hash >> rotate);
hash = (hash + i ) * seed;
}
return (hash + len) * seed;
}
MaHash8v64
Где-то уже видели эту функцию? Конечно, видели. Это - двойник алгоритма MaHash8, только теперь функция возвращает 64-разрядный хэш, тоесть оба 32-разрядных значения, не сжимая из в одно. Сам алгоритм полностью 32-разрядный, скорость его не уменьшилась. Такую манимуляцию можно провести со всеми алгоритмами семейства, в которых структура - это две подфункции. Достоинства алгоритма - высокая скорость, равная алгоритму с 32-разрядным хэшем, простота реализации и очень хорошие показатели по числу коллизий. Функция, безусловно, лидер в нашем забеге, хотя участвует вне конкурса - ведь хэш в два раза больше, чем у других участников.
Для увеличения лавинного эффекта можно использовать простую модификацию с дополнительным преобразованием финального 64-битного значения.
#define LROT14(x) (((x) << 14) | ((x) >> 18 ))
#define RROT14(x) (((x) << 18) | ((x) >> 14 ))
#ifdef HIAVAL
#define LROT64(x) (((x) << 29) | ((x) >> 34 ))
#endif
unsigned long long
MaHash8v64 (unsigned char *str, unsigned int len)
{
unsigned int sh1, sh2, hash1 = len, hash2 = len, i;
unsigned long long digest;
for (i = 0; i != len; i++, str++)
{
hash1 += sTable[( *str + i) & 255];
hash1 = LROT14 (hash1 + ((hash1 << 6) ^ (hash1 >> 11)));
hash2 += sTable[( *str + i) & 255];
hash2 = RROT14 (hash2 + ((hash2 << 6) ^ (hash2 >> 11)));
sh1 = hash1;
sh2 = hash2;
hash1 = ((sh1 >> 16) & 0xffff) | ((sh2 & 0xffff) << 16);
hash2 = ((sh2 >> 16) & 0xffff) | ((sh1 & 0xffff) << 16);
}
#ifdef HIAVAL
digest = (((unsigned long long) hash1) << 32) | ((unsigned long long) hash2 );
digest ^= LROT64(digest + ((digest << 13) ^ (digest >> 23)));
#else
digest = (((unsigned long long) hash2) << 32) | ((unsigned long long) hash1 );
#endif
return digest;
}
MaHash4v64
Опять дежавю? Опять нет. Это модификация существующего алгоритма, аналогично вышерассмотренной 64-разрядной функции.
Также, как и в прошлом варинте, можно усилить лавинный эффект путем добавления дополнительного преобразования. Это немного замедлит алгоритм, поскольку операции выполняются над 64-разрядными беззнаковыми числами, но функция будет выглядеть интереснее.
#define LROT(x) (((x) << 11) | ((x) >> 21 ))
#define RROT(x) (((x) << 21) | ((x) >> 11 ))
#ifdef HIAVAL
#define LROT64(x) (((x) << 29) | ((x) >> 34 ))
#endif
unsigned long long
MaHash4v64 (unsigned char *str, unsigned int len)
{
unsigned int sh1, sh2, hash1 = len, hash2 = len, i;
unsigned long long digest;
for (i = 0; i != len; i++, str++)
{
hash1 += sTable[( *str + i) & 255];
hash1 = LROT (hash1 + ((hash1 << 6) ^ (hash1 >> 8)));
hash2 += sTable[( *str + i) & 255];
hash2 = RROT (hash2 + ((hash2 << 6) ^ (hash2 >> 8)));
sh1 = hash1;
sh2 = hash2;
hash1 = ((sh1 >> 16) & 0xffff) | ((sh2 & 0xffff) << 16);
hash2 = ((sh2 >> 16) & 0xffff) | ((sh1 & 0xffff) << 16);
}
#ifdef HIAVAL
digest = (((unsigned long long) hash1) << 32) | ((unsigned long long) hash2 );
digest ^= LROT64(digest + ((digest << 13) ^ (digest >> 23)));
#else
digest = (((unsigned long long) hash2) << 32) | ((unsigned long long) hash1 );
#endif
return digest;
}
MaHashMR1
Белая ворона? Более чем. Здесь мы имеет саму необычную структуру: четыре “вращающихся” 8-битных регистра накопления, которые модифицируются с помощью двойной табличной замены. На каждом шаге для накопления входного текста выбирается следующий регистр, затем все биты всех регистров циклически сдвигаются на один бит. Функция может иметь любое кол-во итераций. По всей видимости, оптимальным их числом будет три.
#define LROT1(x) (((x) << 1) | ((x) >> 31 ))
#define MR_ITERATIONS 3
union type_regs
{
unsigned long d32;
unsigned char d8[4];
};
unsigned long
MaHashMR1 (unsigned char *str, unsigned int len)
{
unsigned int i, s = 0;
unsigned char val;
union type_regs regs;
regs.d32 = len;
for (i = 0; i != len * MR_ITERATIONS; i++)
{
val = *(str + (i % len));
regs.d8[s] = sTable[(sTable[(val + i) & 255] + regs.d8[s]) & 255];
s = (s + 1) % 4;
regs.d32 = LROT1(regs.d32);
}
return regs.d32;
}
MurmurHash2AM
Как можно улучшить функцию, котороя итак уже близка к оптимальной? Легко. Надо добавить счетчик. Счетчик блока. Ведь счетчик вообще - дело хорошее. Он помогает нам для двух одинаковых блоков вычислить разные значения. Это не совсем то, что даст хорошая табличная подстановка, но уже избавит от множества проблем. Мы не получим таких всплесков на сложных наборах, как исходный вариант. При этом общие результаты пострадать не должны.
Итак, перед вами моя модификация MurmurHash2AM. M- потому, что модификация. AM, как ни странно - тоже имеет смысл - имя автора модификации.
#define mmix(h,k) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
unsigned int MurmurHash2AM ( char * key, unsigned int len)
{
const unsigned int m = 0x5bd1e995;
const int r = 24;
unsigned int l = len, h = 0, i = 1;
const unsigned char * data = (const unsigned char *)key;
while (len >= 4)
{
unsigned int k = *(unsigned int*)data + i++;
mmix(h,k);
data += 4;
len -= 4;
}
unsigned int t = 0;
switch (len)
{
case 3:
t ^= data[2] << 16;
case 2:
t ^= data[1] << 8;
case 1:
t ^= data[0];
};
mmix(h,t);
mmix(h,l);
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}
Итак, приступим к тестированию! Свыше двух миллионов уникальных текстов как в латинице, так и в кириллице обязательно вызовут коллизии. Вопрос только в том, сколько их будет и можно ли как-то превзойти результаты существующих функций? Для того, чтобы тестирование было объективным, проведем не один заход, а целую серию, изменяя входной текст на каждом шаге, постепенно усложняя задачу, чтобы “поймать” функцию на всплеске коллизий.
Примечание: в данном тесте в качестве функции fnv применяется распространенная в сети реализация. Официальный референсный код применяется в fnv1 и fnv1a алгоритмах.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
maPrime2c |
804 |
814 |
810 |
873 |
856 |
869 |
796 |
864 |
836 |
maPrime2d |
844 |
833 |
812 |
801 |
808 |
918 |
835 |
877 |
841 |
maPrime |
878 |
860 |
862 |
781 |
824 |
808 |
874 |
853 |
843 |
MaHash8 |
796 |
858 |
806 |
873 |
893 |
838 |
862 |
843 |
846 |
maPrime2 |
830 |
831 |
863 |
807 |
843 |
871 |
863 |
866 |
847 |
MaHash4 |
826 |
812 |
828 |
831 |
922 |
864 |
888 |
808 |
847 |
MaHashMR1 |
838 |
837 |
849 |
849 |
856 |
850 |
899 |
807 |
848 |
maPrime2a |
822 |
859 |
766 |
916 |
842 |
814 |
880 |
901 |
850 |
maPrime2b |
822 |
859 |
766 |
916 |
842 |
814 |
880 |
901 |
850 |
MaHash11 |
795 |
838 |
870 |
861 |
855 |
868 |
857 |
908 |
857 |
Lookup3 |
886 |
868 |
900 |
785 |
867 |
892 |
831 |
834 |
858 |
MaHash5 |
819 |
832 |
838 |
866 |
944 |
887 |
840 |
846 |
859 |
Murmur2AM |
830 |
863 |
884 |
888 |
878 |
869 |
827 |
849 |
861 |
crc32 |
856 |
856 |
856 |
856 |
886 |
827 |
899 |
859 |
862 |
MaHash3 |
894 |
851 |
876 |
895 |
824 |
862 |
823 |
871 |
862 |
MaHash2 |
819 |
891 |
866 |
832 |
846 |
859 |
875 |
926 |
864 |
MaHash1 |
910 |
839 |
841 |
881 |
899 |
933 |
902 |
884 |
886 |
Murmur2a |
848 |
847 |
922 |
836 |
990 |
1140 |
879 |
861 |
915 |
Faq6 |
947 |
947 |
947 |
947 |
889 |
869 |
906 |
913 |
921 |
OneAtTime |
947 |
947 |
947 |
947 |
889 |
869 |
906 |
913 |
921 |
MaHash7 |
839 |
942 |
1097 |
1082 |
848 |
867 |
847 |
865 |
923 |
MaHash9 |
831 |
932 |
1114 |
1133 |
831 |
889 |
864 |
865 |
932 |
MaHash6 |
864 |
902 |
1077 |
1072 |
897 |
898 |
904 |
848 |
933 |
MaHash/3 |
823 |
928 |
1095 |
1260 |
869 |
885 |
857 |
892 |
951 |
MaHash7/3 |
846 |
938 |
1115 |
1189 |
866 |
877 |
892 |
909 |
954 |
MaHash |
918 |
900 |
1191 |
1275 |
812 |
856 |
892 |
913 |
970 |
maBKDR |
824 |
795 |
840 |
857 |
829 |
1728 |
894 |
1009 |
972 |
Murmur2 |
861 |
864 |
808 |
823 |
1138 |
1832 |
836 |
874 |
1005 |
MaHash10 |
839 |
1006 |
1346 |
1466 |
827 |
869 |
836 |
970 |
1020 |
ROT13 |
987 |
1016 |
1095 |
1129 |
1015 |
964 |
928 |
1459 |
1074 |
Murmur3 |
887 |
860 |
826 |
829 |
2097 |
2330 |
861 |
854 |
1193 |
AP |
873 |
887 |
827 |
813 |
1416 |
4568 |
885 |
842 |
1389 |
LY |
819 |
819 |
819 |
819 |
1748 |
3543 |
883 |
1766 |
1402 |
BKDR |
860 |
860 |
860 |
860 |
1708 |
3548 |
894 |
1906 |
1437 |
fnv1a |
807 |
807 |
807 |
807 |
2650 |
5235 |
910 |
1695 |
1715 |
fnv1 |
869 |
869 |
869 |
869 |
2589 |
5209 |
899 |
1758 |
1741 |
djb |
1152 |
1152 |
1152 |
1152 |
2081 |
3787 |
1180 |
5952 |
2201 |
SBOX |
1511 |
1521 |
1608 |
1594 |
2722 |
4940 |
1530 |
2308 |
2217 |
fnv |
873 |
873 |
873 |
873 |
4436 |
9037 |
800 |
3386 |
2644 |
Rs |
845 |
896 |
877 |
867 |
2092 |
9298 |
802 |
6375 |
2757 |
Crap8 |
851 |
875 |
870 |
886 |
9523 |
9633 |
861 |
868 |
3046 |
SuperFastHash |
4987 |
3889 |
3934 |
3935 |
2066 |
1873 |
3862 |
968 |
3189 |
Js |
3513 |
4151 |
6105 |
6735 |
1009 |
881 |
3350 |
898 |
3330 |
x31 |
3266 |
3227 |
3292 |
3231 |
4930 |
7414 |
2650 |
3053 |
3883 |
GoulburnHash |
5309 |
9635 |
22197 |
26506 |
5218 |
5312 |
5380 |
5311 |
10609 |
Sdbm |
943 |
943 |
943 |
943 |
14996 |
30196 |
869 |
89196 |
17379 |
x17 |
25281 |
25346 |
25254 |
25239 |
26179 |
27892 |
23828 |
1903 |
22615 |
Dek |
6824 |
5474 |
5362 |
5070 |
24564 |
422012 |
8629 |
1820 |
59969 |
CrapWow |
996 |
970 |
1006 |
996 |
397113 |
683161 |
1026 |
2757 |
136003 |
Elf |
52291 |
268965 |
268965 |
268733 |
455236 |
706374 |
49808 |
70326 |
267587 |
PJW-32 |
52291 |
268965 |
268965 |
268733 |
455236 |
706374 |
49808 |
70326 |
267587 |
Fletcher |
434075 |
30303 |
30349 |
36015 |
284334 |
282984 |
250407 |
2174482 |
440369 |
Novak |
753734 |
753734 |
753734 |
753734 |
597509 |
598661 |
729428 |
34043 |
621822 |
Adler |
1952330 |
1952330 |
1952330 |
1952330 |
1951871 |
1951872 |
1952044 |
2709710 |
2046852 |
bp |
2276753 |
2596105 |
2726283 |
2726298 |
2279190 |
2279402 |
2274948 |
2274754 |
2429217 |
Проверим результаты теста на том же наборе данных, но в другой кодировке. Как поведут себя алгоритмы на тех же текстах, но в кодировке cp1251? Наши функции лидируют, хотя в отрыве теперь уже другие финалисты. Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
MaHash3 |
853 |
803 |
871 |
835 |
834 |
871 |
835 |
828 |
841 |
maPrime2c |
875 |
812 |
870 |
859 |
876 |
825 |
832 |
838 |
848 |
crc32 |
854 |
854 |
854 |
854 |
865 |
814 |
837 |
865 |
850 |
maPrime2d |
838 |
860 |
831 |
816 |
854 |
864 |
886 |
860 |
851 |
MaHash4 |
821 |
882 |
826 |
855 |
877 |
856 |
853 |
854 |
853 |
maPrime |
857 |
868 |
832 |
843 |
825 |
801 |
913 |
901 |
855 |
MaHash5 |
860 |
806 |
896 |
865 |
908 |
865 |
840 |
805 |
856 |
MaHash2 |
833 |
861 |
842 |
800 |
851 |
880 |
872 |
916 |
857 |
MaHashMR1 |
846 |
838 |
885 |
878 |
865 |
868 |
875 |
824 |
860 |
Lookup3 |
890 |
869 |
888 |
803 |
897 |
837 |
878 |
830 |
862 |
MaHash11 |
840 |
816 |
877 |
887 |
850 |
871 |
861 |
901 |
863 |
MaHash1 |
856 |
836 |
825 |
854 |
928 |
853 |
895 |
878 |
866 |
Murmur2AM |
851 |
840 |
898 |
856 |
896 |
878 |
842 |
887 |
869 |
MaHash8 |
901 |
871 |
859 |
872 |
874 |
901 |
853 |
834 |
871 |
maPrime2 |
889 |
827 |
890 |
862 |
907 |
868 |
851 |
874 |
871 |
maPrime2a |
883 |
919 |
839 |
902 |
838 |
849 |
864 |
882 |
872 |
maPrime2b |
883 |
919 |
839 |
902 |
838 |
849 |
864 |
882 |
872 |
Murmur2a |
842 |
894 |
852 |
867 |
986 |
1113 |
895 |
862 |
914 |
Faq6 |
950 |
950 |
950 |
950 |
884 |
871 |
922 |
894 |
921 |
OneAtTime |
950 |
950 |
950 |
950 |
884 |
871 |
922 |
894 |
921 |
MaHash7/3 |
824 |
860 |
1055 |
1152 |
890 |
909 |
877 |
878 |
931 |
MaHash9 |
900 |
990 |
1114 |
1137 |
787 |
853 |
846 |
866 |
937 |
MaHash6 |
876 |
942 |
1111 |
1187 |
905 |
859 |
835 |
865 |
948 |
MaHash/3 |
844 |
950 |
1156 |
1172 |
856 |
890 |
899 |
874 |
955 |
MaHash7 |
882 |
933 |
1127 |
1197 |
875 |
855 |
921 |
859 |
956 |
MaHash |
887 |
931 |
1163 |
1249 |
884 |
915 |
878 |
916 |
978 |
maBKDR |
899 |
864 |
801 |
884 |
857 |
1660 |
848 |
1091 |
988 |
Murmur2 |
809 |
821 |
823 |
843 |
1089 |
1934 |
831 |
872 |
1003 |
MaHash10 |
853 |
1053 |
1309 |
1429 |
823 |
897 |
893 |
963 |
1028 |
ROT13 |
952 |
982 |
1070 |
1079 |
1070 |
913 |
944 |
1463 |
1059 |
Murmur3 |
838 |
822 |
833 |
865 |
2076 |
2390 |
889 |
868 |
1198 |
LY |
798 |
798 |
798 |
798 |
1750 |
3387 |
861 |
1747 |
1367 |
AP |
890 |
844 |
867 |
890 |
1424 |
4564 |
924 |
855 |
1407 |
BKDR |
867 |
867 |
867 |
867 |
1677 |
3402 |
847 |
1941 |
1417 |
fnv1a |
849 |
849 |
849 |
849 |
2621 |
5152 |
832 |
1740 |
1718 |
fnv1 |
881 |
881 |
881 |
881 |
2689 |
5303 |
898 |
1725 |
1767 |
SBOX |
1568 |
1516 |
1584 |
1502 |
2764 |
4911 |
1543 |
2333 |
2215 |
fnv |
867 |
867 |
867 |
867 |
4608 |
8993 |
895 |
3391 |
2669 |
Rs |
869 |
877 |
945 |
839 |
2037 |
9292 |
783 |
6524 |
2771 |
Crap8 |
869 |
911 |
866 |
869 |
9358 |
9538 |
914 |
909 |
3029 |
SuperFastHash |
4824 |
3868 |
3869 |
3932 |
1975 |
1866 |
3825 |
947 |
3138 |
Js |
3450 |
4114 |
6108 |
6577 |
983 |
907 |
3298 |
885 |
3290 |
x31 |
3139 |
3092 |
3142 |
3122 |
4903 |
7454 |
2567 |
3622 |
3880 |
djb |
1216 |
1216 |
1216 |
1216 |
24811 |
3740 |
1184 |
6003 |
5075 |
GoulburnHash |
5243 |
9510 |
22240 |
26600 |
5131 |
5434 |
5375 |
5264 |
10600 |
Sdbm |
897 |
897 |
897 |
897 |
14995 |
29758 |
825 |
89227 |
17299 |
x17 |
24994 |
25125 |
25068 |
24998 |
25948 |
27636 |
23828 |
1937 |
22442 |
Dek |
6403 |
5905 |
5685 |
5347 |
24811 |
422429 |
10995 |
1862 |
60430 |
CrapWow |
1018 |
978 |
1005 |
1003 |
397114 |
683147 |
997 |
2791 |
136007 |
PJW-32 |
51274 |
261719 |
261719 |
261271 |
428199 |
650498 |
49215 |
63792 |
253461 |
Fletcher |
441807 |
32747 |
32784 |
40013 |
283951 |
284270 |
259720 |
2187973 |
445408 |
Elf |
51274 |
261719 |
261719 |
261271 |
2279198 |
650498 |
49215 |
63792 |
484836 |
Novak |
738325 |
738325 |
738325 |
738325 |
607665 |
608812 |
713049 |
34024 |
614606 |
Adler |
1959011 |
1959011 |
1959011 |
1959011 |
1958760 |
1958780 |
1959042 |
2708057 |
2052585 |
bp |
2276057 |
2596217 |
2726283 |
2726298 |
2279198 |
2279410 |
2274416 |
2274878 |
2429095 |
Существует довольно известный тест от Сергея Вакуленко, где используется сокращенный набор словарного материала (у меня получилось 326797 слова, результаты теста A совпадают с результатами Сергея). Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
MaHash4 |
4 |
12 |
8 |
8 |
17 |
13 |
14 |
7 |
10 |
MaHash1 |
10 |
12 |
10 |
11 |
10 |
17 |
7 |
10 |
11 |
MaHash6 |
10 |
10 |
11 |
13 |
12 |
13 |
9 |
10 |
11 |
MaHash3 |
11 |
14 |
12 |
10 |
9 |
14 |
9 |
9 |
11 |
crc32 |
13 |
13 |
13 |
13 |
8 |
11 |
11 |
6 |
11 |
MaHash2 |
11 |
10 |
14 |
10 |
8 |
12 |
10 |
14 |
11 |
MaHash5 |
7 |
10 |
9 |
12 |
23 |
11 |
10 |
11 |
12 |
MaHash8 |
7 |
14 |
11 |
12 |
12 |
9 |
13 |
17 |
12 |
ROT13 |
7 |
9 |
11 |
13 |
8 |
14 |
13 |
22 |
12 |
MaHash11 |
10 |
13 |
12 |
16 |
9 |
13 |
14 |
12 |
12 |
Lookup3 |
9 |
13 |
21 |
12 |
8 |
7 |
11 |
19 |
13 |
maPrime |
12 |
11 |
8 |
16 |
17 |
11 |
11 |
14 |
13 |
Murmur2AM |
7 |
15 |
16 |
17 |
11 |
13 |
6 |
16 |
13 |
MaHash7 |
10 |
12 |
9 |
22 |
11 |
15 |
11 |
11 |
13 |
MaHash |
11 |
14 |
15 |
19 |
12 |
8 |
14 |
10 |
13 |
Faq6 |
14 |
14 |
14 |
14 |
8 |
14 |
15 |
11 |
13 |
OneAtTime |
14 |
14 |
14 |
14 |
8 |
14 |
15 |
11 |
13 |
maPrime2c |
17 |
6 |
12 |
6 |
17 |
26 |
11 |
9 |
13 |
MaHash/3 |
14 |
11 |
11 |
17 |
10 |
11 |
10 |
21 |
13 |
MaHashMR1 |
11 |
7 |
14 |
20 |
15 |
10 |
19 |
12 |
14 |
Murmur2a |
18 |
13 |
13 |
15 |
20 |
7 |
6 |
17 |
14 |
maPrime2d |
16 |
14 |
12 |
18 |
11 |
12 |
15 |
12 |
14 |
MaHash9 |
20 |
12 |
19 |
12 |
16 |
9 |
10 |
12 |
14 |
maBKDR |
14 |
14 |
14 |
12 |
12 |
23 |
16 |
9 |
14 |
MaHash7/3 |
15 |
23 |
22 |
14 |
12 |
11 |
6 |
14 |
15 |
Murmur2 |
9 |
22 |
15 |
14 |
12 |
25 |
11 |
13 |
15 |
MaHash10 |
14 |
18 |
11 |
23 |
15 |
14 |
21 |
11 |
16 |
Murmur3 |
17 |
12 |
11 |
19 |
33 |
45 |
11 |
6 |
19 |
LY |
9 |
9 |
9 |
9 |
25 |
61 |
10 |
24 |
20 |
maPrime2 |
32 |
16 |
17 |
13 |
12 |
16 |
37 |
13 |
20 |
BKDR |
11 |
11 |
11 |
11 |
26 |
51 |
14 |
29 |
21 |
maPrime2a |
31 |
15 |
13 |
13 |
15 |
15 |
50 |
14 |
21 |
maPrime2b |
31 |
15 |
13 |
13 |
15 |
15 |
50 |
14 |
21 |
AP |
16 |
19 |
8 |
13 |
26 |
76 |
16 |
13 |
23 |
fnv1a |
6 |
6 |
6 |
6 |
49 |
77 |
17 |
27 |
24 |
fnv1 |
13 |
13 |
13 |
13 |
47 |
75 |
7 |
27 |
26 |
SBOX |
26 |
29 |
22 |
22 |
42 |
66 |
23 |
37 |
33 |
rs |
9 |
8 |
14 |
16 |
31 |
134 |
18 |
77 |
38 |
fnv |
10 |
10 |
10 |
10 |
58 |
151 |
8 |
54 |
39 |
SuperFastHash |
58 |
53 |
59 |
70 |
43 |
31 |
82 |
12 |
51 |
Js |
98 |
110 |
145 |
145 |
20 |
20 |
100 |
15 |
82 |
djb |
84 |
84 |
84 |
84 |
100 |
128 |
79 |
31 |
84 |
x31 |
85 |
84 |
86 |
81 |
114 |
142 |
67 |
23 |
85 |
Crap8 |
16 |
14 |
13 |
12 |
444 |
450 |
19 |
15 |
123 |
GoulburnHash |
69 |
135 |
292 |
371 |
82 |
88 |
74 |
90 |
150 |
Sdbm |
13 |
13 |
13 |
13 |
216 |
429 |
13 |
949 |
207 |
x17 |
417 |
423 |
422 |
420 |
437 |
457 |
469 |
19 |
383 |
Dek |
308 |
251 |
233 |
214 |
3271 |
41670 |
295 |
149 |
5799 |
Elf |
1315 |
4375 |
4375 |
4341 |
23838 |
35022 |
1778 |
999 |
9505 |
PJW-32 |
1315 |
4375 |
4375 |
4341 |
23838 |
35022 |
1778 |
999 |
9505 |
Fletcher |
12950 |
214 |
210 |
217 |
2983 |
2915 |
15101 |
67551 |
12768 |
Novak |
16194 |
16194 |
16194 |
16194 |
11482 |
11511 |
14958 |
588 |
12914 |
CrapWow |
73 |
71 |
63 |
73 |
42618 |
81664 |
136 |
110 |
15601 |
Adler |
53114 |
53114 |
53114 |
53114 |
52896 |
52927 |
53115 |
286829 |
82278 |
bp |
254849 |
290245 |
326781 |
326796 |
255208 |
255229 |
250380 |
250875 |
276295 |
Проведем еще один тест от Сергея Вакуленко, на втором тестовом наборе. Здесь используется сокращенный набор словарного материала (у меня получилось 310595 слов, результаты теста A - это аналог второго теста Сергея). Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
MaHash3 |
8 |
12 |
6 |
5 |
11 |
13 |
8 |
7 |
9 |
Murmur2a |
5 |
8 |
9 |
9 |
10 |
9 |
17 |
4 |
9 |
Murmur2AM |
8 |
11 |
10 |
11 |
10 |
8 |
7 |
8 |
9 |
MaHash5 |
9 |
11 |
7 |
5 |
13 |
10 |
19 |
5 |
10 |
maPrime2c |
10 |
9 |
11 |
7 |
14 |
10 |
12 |
8 |
10 |
MaHash11 |
10 |
17 |
15 |
12 |
9 |
5 |
4 |
10 |
10 |
MaHash1 |
10 |
7 |
10 |
11 |
6 |
13 |
15 |
13 |
11 |
MaHash2 |
11 |
12 |
9 |
10 |
12 |
9 |
15 |
7 |
11 |
maPrime |
7 |
13 |
11 |
9 |
12 |
10 |
8 |
16 |
11 |
MaHash6 |
9 |
8 |
11 |
9 |
12 |
11 |
15 |
11 |
11 |
MaHash8 |
10 |
9 |
15 |
7 |
8 |
13 |
13 |
12 |
11 |
lookup3 |
13 |
12 |
5 |
12 |
13 |
8 |
11 |
13 |
11 |
MaHash |
6 |
12 |
15 |
22 |
13 |
4 |
7 |
11 |
11 |
maPrime2d |
12 |
15 |
11 |
12 |
9 |
12 |
15 |
5 |
11 |
maBKDR |
16 |
9 |
12 |
9 |
8 |
20 |
8 |
12 |
12 |
ROT13 |
9 |
9 |
10 |
10 |
15 |
17 |
9 |
16 |
12 |
MaHash9 |
6 |
9 |
11 |
14 |
12 |
13 |
12 |
19 |
12 |
faq6 |
12 |
12 |
12 |
12 |
12 |
13 |
17 |
10 |
13 |
OneAtTime |
12 |
12 |
12 |
12 |
12 |
13 |
17 |
10 |
13 |
MaHash4 |
8 |
11 |
12 |
12 |
14 |
17 |
15 |
12 |
13 |
maHashMR1 |
8 |
12 |
12 |
10 |
16 |
10 |
20 |
14 |
13 |
crc32 |
14 |
14 |
14 |
14 |
9 |
12 |
11 |
14 |
13 |
MaHash7 |
13 |
13 |
15 |
15 |
10 |
8 |
15 |
14 |
13 |
MaHash10 |
13 |
14 |
18 |
20 |
12 |
12 |
10 |
7 |
13 |
Murmur2 |
13 |
15 |
12 |
11 |
12 |
25 |
12 |
10 |
14 |
maPrime2 |
22 |
11 |
6 |
8 |
4 |
13 |
39 |
13 |
15 |
LY |
7 |
7 |
7 |
7 |
14 |
45 |
12 |
25 |
16 |
maPrime2a |
29 |
10 |
14 |
11 |
13 |
13 |
36 |
12 |
17 |
maPrime2b |
29 |
10 |
14 |
11 |
13 |
13 |
36 |
12 |
17 |
Murmur3 |
6 |
15 |
15 |
15 |
38 |
37 |
8 |
12 |
18 |
BKDR |
13 |
13 |
13 |
13 |
20 |
47 |
11 |
20 |
19 |
FNV1a |
8 |
8 |
8 |
8 |
27 |
68 |
6 |
31 |
21 |
FNV1 |
13 |
13 |
13 |
13 |
36 |
80 |
8 |
16 |
24 |
SBOX |
24 |
20 |
21 |
22 |
33 |
54 |
27 |
45 |
31 |
AP |
31 |
34 |
32 |
34 |
21 |
67 |
23 |
12 |
32 |
RS |
4 |
5 |
11 |
8 |
24 |
120 |
18 |
82 |
34 |
FNV |
14 |
14 |
14 |
14 |
57 |
111 |
6 |
55 |
36 |
SuperFastHash |
50 |
37 |
38 |
48 |
31 |
20 |
72 |
24 |
40 |
Crap8 |
7 |
23 |
14 |
16 |
321 |
315 |
11 |
13 |
90 |
JS |
145 |
153 |
174 |
181 |
27 |
17 |
149 |
11 |
107 |
Goulburn |
85 |
133 |
293 |
362 |
82 |
77 |
70 |
57 |
145 |
x31 |
166 |
160 |
155 |
159 |
175 |
207 |
158 |
34 |
152 |
DJB |
185 |
185 |
185 |
185 |
203 |
231 |
175 |
55 |
176 |
SDBM |
11 |
11 |
11 |
11 |
175 |
357 |
16 |
879 |
184 |
x17 |
596 |
594 |
594 |
595 |
610 |
629 |
638 |
11 |
533 |
DEK |
775 |
723 |
694 |
687 |
1233 |
40424 |
569 |
57 |
5645 |
ELF |
1407 |
4512 |
4512 |
4421 |
33592 |
55251 |
1353 |
888 |
13242 |
PJW-32 |
1407 |
4512 |
4512 |
4421 |
33592 |
55251 |
1353 |
888 |
13242 |
CrapWow |
13 |
8 |
10 |
14 |
39672 |
76255 |
7 |
56 |
14504 |
Novak |
19964 |
19964 |
19964 |
19964 |
16069 |
16092 |
17420 |
476 |
16239 |
Fletcher |
26693 |
296 |
301 |
296 |
2489 |
2463 |
15668 |
83045 |
16406 |
Adler |
45463 |
45463 |
45463 |
45463 |
42930 |
42822 |
49032 |
297984 |
76828 |
BP |
244709 |
285070 |
310579 |
310594 |
245339 |
245360 |
237688 |
238272 |
264701 |
Проведем еще один тест, теперь уже на случаных данных. Тестовый набор - упоррядоченные по возрастанию строки, состоящие из неосмысленного набора латиинских символов и различных знаков, которые получены с помощью генератора псевдослучайных чисел (всего полчилось 2724448 уникальных строк). Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
maPrime |
806 |
820 |
850 |
839 |
832 |
834 |
864 |
897 |
843 |
MaHash8 |
834 |
853 |
851 |
831 |
837 |
868 |
846 |
844 |
846 |
Lookup3 |
890 |
864 |
848 |
841 |
847 |
832 |
828 |
873 |
853 |
MaHash4 |
861 |
842 |
872 |
895 |
857 |
855 |
853 |
854 |
861 |
MaHash2 |
886 |
853 |
858 |
892 |
839 |
889 |
837 |
843 |
862 |
Murmur2AM |
893 |
824 |
849 |
857 |
918 |
862 |
881 |
823 |
863 |
maPrime2c |
833 |
863 |
871 |
861 |
872 |
878 |
858 |
875 |
864 |
MaHash1 |
885 |
821 |
855 |
930 |
821 |
884 |
862 |
855 |
864 |
MaHash3 |
830 |
875 |
890 |
856 |
904 |
847 |
816 |
897 |
864 |
maPrime2d |
877 |
841 |
846 |
893 |
837 |
880 |
888 |
858 |
865 |
maPrime2 |
820 |
859 |
870 |
890 |
855 |
917 |
877 |
835 |
865 |
Murmur2a |
829 |
833 |
863 |
898 |
872 |
858 |
904 |
872 |
866 |
MaHash5 |
895 |
872 |
889 |
813 |
841 |
870 |
891 |
873 |
868 |
MaHash7 |
846 |
891 |
885 |
896 |
886 |
833 |
852 |
869 |
870 |
Faq6 |
880 |
880 |
880 |
880 |
855 |
887 |
843 |
853 |
870 |
OneAtTime |
880 |
880 |
880 |
880 |
855 |
887 |
843 |
853 |
870 |
MaHash11 |
867 |
876 |
846 |
864 |
928 |
877 |
846 |
865 |
871 |
maPrime2a |
845 |
891 |
821 |
871 |
848 |
883 |
965 |
877 |
875 |
maPrime2b |
845 |
891 |
821 |
871 |
848 |
883 |
965 |
877 |
875 |
crc32 |
882 |
882 |
882 |
882 |
880 |
874 |
869 |
865 |
877 |
MaHashMR1 |
911 |
897 |
903 |
858 |
870 |
855 |
886 |
840 |
878 |
Crap8 |
876 |
857 |
841 |
855 |
920 |
944 |
832 |
898 |
878 |
MaHash10 |
878 |
897 |
890 |
997 |
870 |
813 |
849 |
843 |
880 |
MaHash6 |
821 |
896 |
941 |
932 |
898 |
855 |
851 |
849 |
880 |
MaHash |
920 |
901 |
930 |
964 |
872 |
876 |
869 |
876 |
901 |
MaHash9 |
902 |
901 |
963 |
935 |
878 |
864 |
910 |
887 |
905 |
ROT13 |
888 |
911 |
984 |
1022 |
910 |
857 |
879 |
1087 |
942 |
maBKDR |
873 |
886 |
901 |
851 |
878 |
1704 |
856 |
820 |
971 |
Murmur2 |
866 |
845 |
828 |
870 |
1079 |
1859 |
865 |
865 |
1010 |
SuperFastHash |
988 |
1002 |
949 |
960 |
1021 |
1247 |
963 |
2213 |
1168 |
Murmur3 |
889 |
826 |
845 |
893 |
2117 |
2139 |
869 |
801 |
1172 |
LY |
822 |
822 |
822 |
822 |
1644 |
3465 |
863 |
1780 |
1380 |
BKDR |
832 |
832 |
832 |
832 |
1664 |
3531 |
871 |
1655 |
1381 |
AP |
867 |
861 |
871 |
855 |
1543 |
4951 |
892 |
876 |
1465 |
fnv1a |
857 |
857 |
857 |
857 |
2668 |
5204 |
911 |
1673 |
1736 |
fnv1 |
889 |
889 |
889 |
889 |
2574 |
5095 |
870 |
1823 |
1740 |
SBOX |
1550 |
1516 |
1542 |
1586 |
2681 |
4875 |
1552 |
2256 |
2195 |
fnv |
862 |
862 |
862 |
862 |
4525 |
8844 |
850 |
3453 |
2640 |
Rs |
839 |
854 |
915 |
865 |
2026 |
9200 |
854 |
6495 |
2756 |
Js |
12769 |
13431 |
15301 |
15842 |
1479 |
838 |
12964 |
819 |
9180 |
GoulburnHash |
5174 |
9438 |
21959 |
26284 |
5153 |
5116 |
5243 |
5253 |
10453 |
djb |
11565 |
11565 |
11565 |
11565 |
12340 |
14002 |
11706 |
1860 |
10771 |
x31 |
12829 |
12803 |
12804 |
12786 |
14173 |
16165 |
12907 |
1738 |
12026 |
Sdbm |
901 |
901 |
901 |
901 |
15405 |
30041 |
885 |
57217 |
13394 |
x17 |
32369 |
32332 |
32338 |
32361 |
33265 |
34996 |
32192 |
1734 |
28948 |
Dek |
12084 |
12053 |
12093 |
12049 |
119473 |
368879 |
12107 |
920 |
68707 |
CrapWow |
907 |
864 |
853 |
857 |
351663 |
702929 |
865 |
863 |
132475 |
Fletcher |
43725 |
841 |
871 |
895 |
55367 |
55265 |
43769 |
929201 |
141242 |
Novak |
176178 |
176178 |
176178 |
176178 |
149533 |
151574 |
176405 |
46132 |
153545 |
Elf |
47250 |
237952 |
237952 |
237883 |
212765 |
333799 |
47297 |
14059 |
171120 |
PJW-32 |
47250 |
237952 |
237952 |
237883 |
212765 |
333799 |
47297 |
14059 |
171120 |
Adler |
222626 |
222626 |
222626 |
222626 |
148843 |
140574 |
222285 |
2668138 |
508793 |
bp |
3301 |
285883 |
2548867 |
2724447 |
3456 |
3456 |
3257 |
3387 |
697007 |
Контрольный тест на случаных данных - теперь немного более жесткий, тексты длиннее. Тестовый набор - упорядоченные по возрастанию строки, состоящие из неосмысленного набора латиинских и кириллистических символов (в кодировке cp1251), цифр, которые получены с помощью генератора псевдослучайных чисел (всего полчилось 2725573 уникальных строк, длиной от 2 до 128 символов). Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
MaHash8 |
848 |
850 |
845 |
861 |
856 |
829 |
856 |
827 |
847 |
Murmur2AM |
837 |
841 |
845 |
855 |
869 |
858 |
823 |
857 |
848 |
MaHash11 |
838 |
866 |
866 |
855 |
795 |
850 |
914 |
822 |
851 |
faq6 |
843 |
843 |
843 |
843 |
845 |
882 |
844 |
885 |
854 |
OneAtTime |
843 |
843 |
843 |
843 |
845 |
882 |
844 |
885 |
854 |
MaHash5 |
885 |
878 |
804 |
858 |
871 |
794 |
851 |
894 |
854 |
maPrime2c |
899 |
833 |
839 |
819 |
842 |
901 |
831 |
891 |
857 |
maHashMR1 |
869 |
878 |
808 |
846 |
861 |
830 |
881 |
886 |
857 |
lookup3 |
833 |
886 |
836 |
817 |
889 |
889 |
870 |
851 |
859 |
maPrime2d |
866 |
843 |
847 |
879 |
869 |
885 |
871 |
830 |
861 |
MaHash2 |
856 |
876 |
894 |
907 |
840 |
841 |
830 |
861 |
863 |
maPrime2a |
868 |
853 |
885 |
853 |
822 |
905 |
871 |
858 |
864 |
maPrime2b |
868 |
853 |
885 |
853 |
822 |
905 |
871 |
858 |
864 |
MaHash1 |
904 |
859 |
896 |
861 |
880 |
873 |
844 |
830 |
868 |
MaHash4 |
875 |
903 |
880 |
863 |
820 |
858 |
880 |
885 |
871 |
MaHash9 |
856 |
859 |
897 |
918 |
858 |
866 |
842 |
869 |
871 |
Murmur2a |
907 |
867 |
831 |
844 |
865 |
893 |
881 |
887 |
872 |
MaHash3 |
914 |
888 |
850 |
843 |
896 |
868 |
855 |
870 |
873 |
crc32 |
850 |
850 |
850 |
850 |
924 |
935 |
835 |
900 |
874 |
maPrime2 |
894 |
890 |
878 |
892 |
880 |
850 |
852 |
859 |
874 |
maPrime |
873 |
858 |
905 |
892 |
821 |
850 |
909 |
890 |
875 |
MaHash |
842 |
824 |
911 |
915 |
898 |
866 |
868 |
877 |
875 |
Crap8 |
877 |
911 |
855 |
863 |
899 |
947 |
868 |
844 |
883 |
MaHash7 |
937 |
882 |
868 |
942 |
848 |
892 |
872 |
856 |
887 |
MaHash6 |
876 |
931 |
897 |
923 |
881 |
841 |
879 |
870 |
887 |
MaHash10 |
881 |
872 |
913 |
1001 |
920 |
857 |
806 |
870 |
890 |
ROT13 |
907 |
931 |
1022 |
1024 |
897 |
899 |
919 |
961 |
945 |
maBKDR |
891 |
938 |
847 |
864 |
820 |
1759 |
861 |
886 |
983 |
Murmur2 |
901 |
812 |
817 |
827 |
1092 |
1933 |
885 |
884 |
1019 |
SuperFastHash |
943 |
955 |
1002 |
989 |
1096 |
1275 |
979 |
1754 |
1124 |
Murmur3 |
877 |
885 |
860 |
856 |
2144 |
2236 |
861 |
889 |
1201 |
LY |
861 |
861 |
861 |
861 |
1725 |
3409 |
849 |
1741 |
1396 |
BKDR |
889 |
889 |
889 |
889 |
1718 |
3386 |
859 |
1786 |
1413 |
FNV1 |
825 |
825 |
825 |
825 |
2571 |
5241 |
885 |
1716 |
1714 |
FNV1a |
884 |
884 |
884 |
884 |
2597 |
5173 |
918 |
1752 |
1747 |
AP |
1425 |
1435 |
1391 |
1392 |
1562 |
4926 |
1431 |
854 |
1802 |
SBOX |
1566 |
1500 |
1518 |
1570 |
2689 |
4739 |
1509 |
2302 |
2174 |
FNV |
927 |
927 |
927 |
927 |
4597 |
9030 |
828 |
3754 |
2740 |
RS |
865 |
892 |
820 |
851 |
1984 |
9250 |
888 |
6524 |
2759 |
JS |
9684 |
10361 |
12301 |
12861 |
1180 |
884 |
9671 |
837 |
7222 |
DJB |
9768 |
9768 |
9768 |
9768 |
10575 |
12266 |
9782 |
1687 |
9173 |
x31 |
10644 |
10702 |
10610 |
10637 |
11946 |
14061 |
10609 |
1702 |
10114 |
Goulburn |
5240 |
9647 |
22254 |
26050 |
5127 |
5202 |
5214 |
5089 |
10478 |
SDBM |
911 |
911 |
911 |
911 |
15040 |
30057 |
859 |
54841 |
13055 |
x17 |
25020 |
25017 |
24953 |
24982 |
25872 |
27546 |
25080 |
1684 |
22519 |
DEK |
10477 |
10590 |
10555 |
10569 |
118188 |
367491 |
10628 |
903 |
67425 |
ELF |
40318 |
232079 |
232079 |
232100 |
96275 |
146751 |
40854 |
14176 |
129329 |
PJW-32 |
40318 |
232079 |
232079 |
232100 |
96275 |
146751 |
40854 |
14176 |
129329 |
CrapWow |
859 |
862 |
904 |
865 |
351728 |
702936 |
842 |
840 |
132480 |
Fletcher |
38147 |
883 |
872 |
901 |
54438 |
54905 |
38117 |
911473 |
137467 |
Novak |
177615 |
177615 |
177615 |
177615 |
153819 |
155608 |
177681 |
48437 |
155751 |
Adler |
52773 |
52773 |
52773 |
52773 |
33169 |
30881 |
52937 |
2586412 |
364311 |
BP |
2580 |
257610 |
2725557 |
2725572 |
2651 |
2651 |
2626 |
2523 |
715221 |
Еще один жесткий тест на случаных данных - синтетический, на однотипных текстах с ограниченным набором символов. Тестовый набор - упорядоченные по возрастанию строки, состоящие из неосмысленного набора латиинских символов в верхнем регистре, причем строки имеют частичные совпадения (всего полчилось 2690227 уникальных строк, длиной от 3 до 64 символов). Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
maHashMR1 |
797 |
830 |
818 |
818 |
820 |
847 |
771 |
846 |
818 |
MaHash8 |
825 |
820 |
807 |
871 |
830 |
867 |
801 |
804 |
828 |
MaHash5 |
852 |
832 |
787 |
818 |
825 |
824 |
834 |
870 |
830 |
MaHash2 |
873 |
819 |
870 |
867 |
794 |
811 |
846 |
795 |
834 |
lookup3 |
889 |
799 |
793 |
814 |
854 |
872 |
855 |
802 |
835 |
maPrime2 |
807 |
821 |
867 |
817 |
803 |
829 |
884 |
860 |
836 |
MaHash11 |
878 |
838 |
850 |
809 |
852 |
773 |
869 |
846 |
839 |
MaHash1 |
859 |
818 |
847 |
842 |
822 |
820 |
849 |
868 |
841 |
MaHash4 |
826 |
809 |
865 |
838 |
889 |
853 |
809 |
843 |
842 |
maPrime2c |
832 |
838 |
856 |
813 |
864 |
859 |
806 |
877 |
843 |
MaHash3 |
756 |
829 |
885 |
883 |
860 |
829 |
871 |
835 |
844 |
maPrime2a |
822 |
836 |
824 |
847 |
836 |
857 |
880 |
852 |
844 |
maPrime2b |
822 |
836 |
824 |
847 |
836 |
857 |
880 |
852 |
844 |
maPrime2d |
820 |
863 |
825 |
841 |
859 |
838 |
840 |
883 |
846 |
maPrime |
837 |
853 |
834 |
844 |
886 |
886 |
857 |
785 |
848 |
MaHash6 |
829 |
849 |
900 |
858 |
836 |
864 |
866 |
791 |
849 |
Murmur2a |
821 |
827 |
802 |
881 |
866 |
885 |
909 |
808 |
850 |
MaHash7 |
860 |
857 |
881 |
879 |
820 |
779 |
860 |
868 |
851 |
crc32 |
856 |
856 |
856 |
856 |
871 |
826 |
828 |
858 |
851 |
MaHash9 |
843 |
852 |
903 |
905 |
874 |
875 |
812 |
787 |
856 |
Murmur2AM |
895 |
826 |
860 |
855 |
858 |
855 |
823 |
894 |
858 |
MaHash |
854 |
876 |
891 |
923 |
879 |
814 |
848 |
851 |
867 |
faq6 |
923 |
923 |
923 |
923 |
853 |
800 |
828 |
831 |
876 |
OneAtTime |
923 |
923 |
923 |
923 |
853 |
800 |
828 |
831 |
876 |
MaHash10 |
811 |
834 |
943 |
927 |
884 |
858 |
856 |
893 |
876 |
ROT13 |
876 |
899 |
966 |
999 |
949 |
883 |
889 |
982 |
930 |
maBKDR |
850 |
869 |
798 |
854 |
843 |
1608 |
849 |
845 |
940 |
Murmur2 |
876 |
882 |
858 |
808 |
1072 |
1821 |
856 |
830 |
1000 |
SuperFastHash |
1053 |
1008 |
1041 |
1006 |
1020 |
1297 |
1071 |
911 |
1051 |
Murmur3 |
799 |
841 |
893 |
840 |
1734 |
1939 |
865 |
878 |
1099 |
Crap8 |
831 |
795 |
868 |
855 |
2613 |
2662 |
847 |
816 |
1286 |
LY |
840 |
840 |
840 |
840 |
1737 |
3315 |
829 |
1694 |
1367 |
BKDR |
876 |
876 |
876 |
876 |
1683 |
3425 |
801 |
1774 |
1398 |
AP |
813 |
822 |
852 |
834 |
1546 |
4861 |
852 |
855 |
1429 |
DJB |
840 |
840 |
840 |
840 |
1649 |
3340 |
852 |
2488 |
1461 |
x31 |
815 |
906 |
912 |
822 |
2080 |
4189 |
832 |
1810 |
1546 |
FNV1 |
841 |
841 |
841 |
841 |
2495 |
5050 |
815 |
1655 |
1672 |
FNV1a |
833 |
833 |
833 |
833 |
2592 |
5201 |
802 |
1711 |
1705 |
SBOX |
1456 |
1485 |
1533 |
1526 |
2637 |
4845 |
1516 |
2277 |
2159 |
JS |
2261 |
2871 |
4717 |
5291 |
877 |
844 |
2225 |
920 |
2501 |
FNV |
872 |
872 |
872 |
872 |
4374 |
8873 |
881 |
3301 |
2615 |
RS |
789 |
838 |
889 |
854 |
2006 |
8868 |
851 |
6333 |
2679 |
Goulburn |
5114 |
9120 |
21383 |
25464 |
5120 |
5095 |
5160 |
5106 |
10195 |
SDBM |
817 |
817 |
817 |
817 |
14471 |
28892 |
855 |
61316 |
13600 |
x17 |
16230 |
16279 |
16265 |
16297 |
17076 |
18732 |
16191 |
1727 |
14850 |
DEK |
947 |
954 |
919 |
916 |
112745 |
356921 |
970 |
977 |
59419 |
Novak |
111385 |
111385 |
111385 |
111385 |
92589 |
94547 |
111460 |
17383 |
95190 |
CrapWow |
963 |
993 |
991 |
996 |
351443 |
700750 |
975 |
907 |
132252 |
Fletcher |
30522 |
2375 |
2359 |
4453 |
75912 |
76548 |
30573 |
1193428 |
177021 |
ELF |
31966 |
219295 |
219295 |
218834 |
294173 |
462650 |
32056 |
22791 |
187633 |
PJW-32 |
31966 |
219295 |
219295 |
218834 |
294173 |
462650 |
32056 |
22791 |
187633 |
Adler |
522275 |
522275 |
522275 |
522275 |
513410 |
513397 |
521984 |
2665529 |
787928 |
BP |
1118198 |
2411300 |
2690211 |
2690226 |
1128132 |
1128132 |
1120296 |
1128264 |
1676845 |
Усложняем тест на случаных данных на текстах, имеющих частичные совпадения. Тестовый набор - упорядоченные по возрастанию строки, состоящие из неосмысленного набора латиинских символов в верхнем и нижнем регистре, а так же чисел (всего полчилось 2724332 уникальных строк, длиной от 3 до 253 символов). Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
MaHash1 |
834 |
888 |
835 |
877 |
848 |
805 |
836 |
833 |
845 |
Murmur2a |
858 |
825 |
881 |
811 |
823 |
876 |
851 |
884 |
851 |
MaHash6 |
826 |
824 |
828 |
874 |
916 |
861 |
846 |
849 |
853 |
MaHash4 |
839 |
821 |
785 |
910 |
880 |
835 |
895 |
867 |
854 |
maPrime2 |
832 |
842 |
862 |
886 |
862 |
864 |
830 |
885 |
858 |
MaHash2 |
867 |
860 |
912 |
848 |
878 |
854 |
833 |
855 |
863 |
maPrime2a |
903 |
865 |
852 |
893 |
820 |
894 |
845 |
836 |
864 |
maPrime2b |
903 |
865 |
852 |
893 |
820 |
894 |
845 |
836 |
864 |
Murmur2AM |
870 |
859 |
902 |
868 |
890 |
852 |
825 |
853 |
865 |
lookup3 |
874 |
864 |
826 |
886 |
856 |
889 |
867 |
860 |
865 |
MaHash10 |
849 |
863 |
966 |
870 |
906 |
787 |
807 |
880 |
866 |
MaHash11 |
930 |
861 |
870 |
899 |
848 |
807 |
887 |
834 |
867 |
crc32 |
877 |
877 |
877 |
877 |
826 |
878 |
845 |
883 |
868 |
maPrime2c |
837 |
870 |
878 |
889 |
888 |
879 |
842 |
868 |
869 |
MaHash8 |
849 |
856 |
862 |
876 |
825 |
878 |
897 |
912 |
869 |
MaHash3 |
868 |
852 |
906 |
854 |
891 |
928 |
862 |
810 |
871 |
MaHash5 |
914 |
865 |
871 |
855 |
853 |
841 |
873 |
904 |
872 |
maHashMR1 |
864 |
871 |
825 |
869 |
913 |
876 |
899 |
862 |
872 |
maPrime |
859 |
836 |
899 |
872 |
845 |
904 |
863 |
905 |
873 |
MaHash |
882 |
877 |
829 |
902 |
871 |
904 |
840 |
913 |
877 |
Crap8 |
877 |
891 |
917 |
842 |
871 |
880 |
899 |
856 |
879 |
MaHash7 |
868 |
904 |
923 |
872 |
863 |
873 |
878 |
871 |
882 |
MaHash9 |
912 |
857 |
857 |
942 |
898 |
858 |
885 |
847 |
882 |
maPrime2d |
910 |
877 |
889 |
866 |
868 |
897 |
851 |
918 |
885 |
faq6 |
903 |
903 |
903 |
903 |
837 |
842 |
904 |
910 |
888 |
OneAtTime |
903 |
903 |
903 |
903 |
837 |
842 |
904 |
910 |
888 |
ROT13 |
912 |
937 |
1011 |
1035 |
936 |
855 |
906 |
927 |
940 |
Murmur3 |
850 |
913 |
845 |
868 |
1027 |
1365 |
862 |
914 |
956 |
maBKDR |
887 |
830 |
815 |
888 |
839 |
1666 |
893 |
913 |
966 |
SuperFastHash |
971 |
944 |
964 |
924 |
1031 |
1020 |
980 |
1110 |
993 |
Murmur2 |
895 |
884 |
816 |
851 |
1113 |
1844 |
877 |
902 |
1023 |
BKDR |
841 |
841 |
841 |
841 |
1688 |
3481 |
828 |
1658 |
1377 |
LY |
891 |
891 |
891 |
891 |
1752 |
3427 |
806 |
1690 |
1405 |
AP |
838 |
877 |
856 |
866 |
1453 |
4996 |
927 |
890 |
1463 |
FNV1a |
868 |
868 |
868 |
868 |
2604 |
5213 |
882 |
1721 |
1737 |
FNV1 |
863 |
863 |
863 |
863 |
2653 |
5225 |
826 |
1748 |
1738 |
SBOX |
1581 |
1546 |
1508 |
1556 |
2814 |
4900 |
1527 |
2224 |
2207 |
DJB |
1842 |
1842 |
1842 |
1842 |
2676 |
4492 |
1920 |
1656 |
2264 |
JS |
1844 |
2511 |
4524 |
4997 |
935 |
882 |
1903 |
862 |
2307 |
x31 |
1938 |
1917 |
1935 |
1922 |
3244 |
5440 |
1958 |
1675 |
2504 |
FNV |
837 |
837 |
837 |
837 |
4487 |
8929 |
894 |
3501 |
2645 |
RS |
866 |
894 |
880 |
866 |
1992 |
9265 |
868 |
7288 |
2865 |
x17 |
3821 |
3818 |
3772 |
3775 |
4668 |
6368 |
3826 |
1697 |
3968 |
Goulburn |
5122 |
9298 |
21945 |
26004 |
5190 |
5190 |
5233 |
5352 |
10417 |
SDBM |
825 |
825 |
825 |
825 |
15187 |
30151 |
824 |
54488 |
12994 |
Novak |
21645 |
21645 |
21645 |
21645 |
18381 |
20351 |
21631 |
6567 |
19189 |
DEK |
1955 |
1974 |
1945 |
1931 |
85310 |
335483 |
1921 |
873 |
53924 |
Fletcher |
9639 |
874 |
843 |
857 |
55675 |
55338 |
9600 |
592448 |
90659 |
ELF |
18528 |
212242 |
212242 |
212649 |
71787 |
112449 |
18759 |
15559 |
109277 |
PJW-32 |
18528 |
212242 |
212242 |
212649 |
71787 |
112449 |
18759 |
15559 |
109277 |
CrapWow |
877 |
857 |
905 |
813 |
336727 |
684855 |
883 |
857 |
128347 |
Adler |
16954 |
16954 |
16954 |
16954 |
13136 |
12908 |
16854 |
2370151 |
310108 |
BP |
1113890 |
1445770 |
2724316 |
2724331 |
1114160 |
1114160 |
1114126 |
1114432 |
1558148 |
Немного другой вариант теста - ограничим его пространством русских текстов. Тестовый набор - упорядоченные по возрастанию строки, состоящие из неосмысленного набора кириллических символов в верхнем и нижнем регистре (всего получилось 2724012 уникальных строки, длиной от 3 до 253 символов). Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
MaHash1 |
874 |
793 |
838 |
833 |
860 |
828 |
893 |
869 |
849 |
maPrime2a |
803 |
833 |
912 |
858 |
854 |
869 |
841 |
845 |
852 |
maPrime2b |
803 |
833 |
912 |
858 |
854 |
869 |
841 |
845 |
852 |
maPrime2 |
871 |
853 |
808 |
806 |
860 |
887 |
858 |
890 |
854 |
Murmur2a |
840 |
843 |
827 |
870 |
892 |
879 |
832 |
853 |
855 |
maPrime2d |
826 |
802 |
886 |
890 |
904 |
896 |
860 |
801 |
858 |
maPrime |
859 |
846 |
863 |
851 |
828 |
884 |
875 |
861 |
858 |
maHashMR1 |
895 |
873 |
896 |
815 |
840 |
827 |
895 |
845 |
861 |
MaHash11 |
886 |
870 |
868 |
825 |
922 |
860 |
855 |
804 |
861 |
maPrime2c |
867 |
919 |
866 |
812 |
827 |
821 |
880 |
919 |
864 |
crc32 |
857 |
857 |
857 |
857 |
866 |
870 |
835 |
913 |
864 |
MaHash7 |
857 |
885 |
846 |
870 |
910 |
891 |
840 |
820 |
865 |
MaHash9 |
906 |
829 |
878 |
950 |
871 |
806 |
847 |
845 |
867 |
MaHash4 |
923 |
859 |
864 |
871 |
848 |
855 |
863 |
849 |
867 |
MaHash5 |
874 |
798 |
859 |
862 |
854 |
897 |
922 |
868 |
867 |
lookup3 |
874 |
859 |
935 |
894 |
816 |
864 |
832 |
864 |
867 |
MaHash |
871 |
829 |
915 |
871 |
879 |
908 |
859 |
811 |
868 |
Crap8 |
896 |
877 |
861 |
805 |
904 |
879 |
877 |
844 |
868 |
MaHash8 |
859 |
830 |
873 |
880 |
893 |
857 |
883 |
872 |
868 |
MaHash3 |
918 |
875 |
855 |
852 |
833 |
883 |
898 |
844 |
870 |
MaHash2 |
848 |
923 |
881 |
911 |
833 |
905 |
852 |
829 |
873 |
faq6 |
873 |
873 |
873 |
873 |
859 |
908 |
877 |
882 |
877 |
OneAtTime |
873 |
873 |
873 |
873 |
859 |
908 |
877 |
882 |
877 |
Murmur2AM |
850 |
902 |
848 |
827 |
925 |
904 |
874 |
896 |
878 |
MaHash6 |
866 |
842 |
924 |
849 |
889 |
856 |
915 |
896 |
880 |
MaHash10 |
900 |
888 |
845 |
880 |
848 |
892 |
915 |
870 |
880 |
ROT13 |
857 |
891 |
971 |
988 |
865 |
927 |
926 |
910 |
917 |
Murmur3 |
877 |
890 |
844 |
879 |
1047 |
1329 |
860 |
876 |
950 |
maBKDR |
868 |
893 |
885 |
882 |
886 |
1598 |
872 |
819 |
963 |
SuperFastHash |
974 |
983 |
948 |
957 |
970 |
951 |
987 |
1043 |
977 |
Murmur2 |
875 |
850 |
870 |
820 |
1098 |
1916 |
841 |
829 |
1012 |
LY |
861 |
861 |
861 |
861 |
1766 |
3517 |
807 |
1734 |
1409 |
BKDR |
874 |
874 |
874 |
874 |
1693 |
3547 |
863 |
1710 |
1414 |
AP |
886 |
899 |
959 |
975 |
1402 |
4905 |
857 |
855 |
1467 |
FNV1 |
837 |
837 |
837 |
837 |
2475 |
5032 |
852 |
1711 |
1677 |
FNV1a |
899 |
899 |
899 |
899 |
2612 |
5119 |
868 |
1724 |
1740 |
DJB |
1441 |
1441 |
1441 |
1441 |
2327 |
3998 |
1415 |
1794 |
1912 |
JS |
1516 |
2161 |
4057 |
4739 |
942 |
875 |
1499 |
890 |
2085 |
x31 |
1475 |
1524 |
1494 |
1476 |
2734 |
4998 |
1537 |
1762 |
2125 |
SBOX |
1513 |
1560 |
1579 |
1565 |
2711 |
4877 |
1501 |
2344 |
2206 |
FNV |
846 |
846 |
846 |
846 |
4516 |
9011 |
914 |
3446 |
2659 |
RS |
846 |
855 |
872 |
829 |
2133 |
8986 |
848 |
7345 |
2839 |
x17 |
3344 |
3400 |
3336 |
3373 |
4280 |
6033 |
3293 |
1673 |
3592 |
Goulburn |
5251 |
9446 |
21981 |
26409 |
5241 |
5217 |
5137 |
5045 |
10466 |
SDBM |
859 |
859 |
859 |
859 |
14953 |
30026 |
868 |
54764 |
13006 |
Novak |
20942 |
20942 |
20942 |
20942 |
18447 |
20553 |
20971 |
6482 |
18778 |
DEK |
1389 |
1423 |
1405 |
1468 |
84158 |
335120 |
1463 |
911 |
53417 |
Fletcher |
9593 |
850 |
883 |
865 |
55310 |
55398 |
9602 |
595436 |
90992 |
ELF |
16591 |
211811 |
211811 |
212637 |
20258 |
26499 |
16287 |
13874 |
91221 |
PJW-32 |
16591 |
211811 |
211811 |
212637 |
20258 |
26499 |
16287 |
13874 |
91221 |
CrapWow |
854 |
851 |
809 |
836 |
337043 |
683355 |
919 |
880 |
128193 |
Adler |
15726 |
15726 |
15726 |
15726 |
15739 |
15912 |
15744 |
2416877 |
315897 |
BP |
1199775 |
1656149 |
2723996 |
2724011 |
1199820 |
1199820 |
1200286 |
1200370 |
1638028 |
Расширим наш тест на случайных данных - теперь он включает практически весь набор возможных печатных символов. Тестовый набор - упорядоченные по возрастанию строки, состоящие из неосмысленного набора латинских, кириллических символов в верхнем и нижнем регистре, цифр, знаков (всего получилось 2724564 уникальных строки, длиной от 3 до 253 символов). Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
maPrime2 |
878 |
851 |
867 |
848 |
829 |
813 |
816 |
853 |
844 |
MaHash8 |
837 |
873 |
832 |
852 |
827 |
839 |
944 |
828 |
854 |
MaHash5 |
856 |
872 |
801 |
848 |
850 |
884 |
877 |
848 |
855 |
Murmur2AM |
884 |
833 |
863 |
827 |
835 |
902 |
869 |
840 |
857 |
Murmur2a |
865 |
817 |
835 |
847 |
874 |
854 |
852 |
917 |
858 |
MaHash10 |
843 |
862 |
867 |
888 |
871 |
820 |
890 |
825 |
858 |
MaHash7 |
833 |
852 |
856 |
887 |
903 |
817 |
879 |
848 |
859 |
lookup3 |
869 |
870 |
886 |
846 |
909 |
828 |
844 |
831 |
860 |
MaHash11 |
847 |
856 |
931 |
855 |
876 |
825 |
845 |
859 |
862 |
maPrime2d |
838 |
824 |
865 |
886 |
882 |
921 |
821 |
866 |
863 |
MaHash4 |
914 |
875 |
886 |
806 |
880 |
899 |
790 |
877 |
866 |
crc32 |
876 |
876 |
876 |
876 |
862 |
870 |
876 |
817 |
866 |
maPrime |
868 |
858 |
885 |
846 |
834 |
879 |
879 |
900 |
869 |
MaHash9 |
872 |
864 |
919 |
884 |
799 |
818 |
916 |
885 |
870 |
maPrime2c |
889 |
888 |
844 |
887 |
874 |
835 |
853 |
895 |
871 |
MaHash3 |
906 |
830 |
861 |
891 |
893 |
881 |
887 |
833 |
873 |
maPrime2a |
834 |
840 |
885 |
884 |
887 |
850 |
910 |
894 |
873 |
maPrime2b |
834 |
840 |
885 |
884 |
887 |
850 |
910 |
894 |
873 |
MaHash2 |
841 |
903 |
888 |
913 |
901 |
802 |
863 |
877 |
874 |
Crap8 |
850 |
821 |
933 |
903 |
855 |
859 |
878 |
893 |
874 |
MaHash6 |
868 |
894 |
843 |
900 |
856 |
866 |
890 |
876 |
874 |
faq6 |
887 |
887 |
887 |
887 |
861 |
858 |
871 |
863 |
875 |
OneAtTime |
887 |
887 |
887 |
887 |
861 |
858 |
871 |
863 |
875 |
MaHash |
922 |
892 |
875 |
841 |
864 |
832 |
881 |
894 |
875 |
MaHash1 |
925 |
882 |
855 |
881 |
913 |
862 |
868 |
868 |
882 |
maHashMR1 |
891 |
858 |
927 |
873 |
871 |
878 |
885 |
875 |
882 |
ROT13 |
898 |
930 |
1022 |
1038 |
903 |
880 |
892 |
886 |
931 |
Murmur3 |
849 |
874 |
877 |
861 |
1019 |
1330 |
851 |
829 |
936 |
SuperFastHash |
918 |
945 |
963 |
909 |
1016 |
978 |
949 |
971 |
956 |
maBKDR |
866 |
886 |
857 |
893 |
820 |
1788 |
857 |
852 |
977 |
Murmur2 |
843 |
897 |
914 |
900 |
1101 |
1806 |
824 |
892 |
1022 |
BKDR |
933 |
933 |
933 |
933 |
1723 |
3473 |
887 |
1777 |
1449 |
LY |
932 |
932 |
932 |
932 |
1748 |
3596 |
870 |
1793 |
1467 |
AP |
898 |
902 |
873 |
879 |
1514 |
4994 |
850 |
838 |
1469 |
FNV1 |
843 |
843 |
843 |
843 |
2652 |
5182 |
866 |
1649 |
1715 |
DJB |
1280 |
1280 |
1280 |
1280 |
2085 |
3849 |
1151 |
1678 |
1735 |
FNV1a |
884 |
884 |
884 |
884 |
2603 |
5227 |
857 |
1729 |
1744 |
JS |
1241 |
1859 |
3725 |
4442 |
906 |
861 |
1193 |
872 |
1887 |
x31 |
1232 |
1211 |
1258 |
1213 |
2513 |
4729 |
1220 |
1801 |
1897 |
SBOX |
1595 |
1484 |
1471 |
1574 |
2685 |
4982 |
1522 |
2432 |
2218 |
x17 |
2049 |
1996 |
2089 |
2055 |
2870 |
4557 |
1998 |
1699 |
2414 |
FNV |
904 |
904 |
904 |
904 |
4452 |
9012 |
866 |
3451 |
2675 |
RS |
866 |
885 |
891 |
838 |
2029 |
9416 |
871 |
7228 |
2878 |
Goulburn |
5132 |
9309 |
22013 |
26229 |
5266 |
5199 |
5140 |
5236 |
10441 |
SDBM |
848 |
848 |
848 |
848 |
15251 |
29952 |
820 |
54526 |
12993 |
Novak |
21251 |
21251 |
21251 |
21251 |
18445 |
20528 |
21143 |
6616 |
18967 |
DEK |
1230 |
1202 |
1224 |
1218 |
83876 |
334433 |
1257 |
864 |
53163 |
Fletcher |
4888 |
837 |
826 |
849 |
54876 |
55063 |
4753 |
590556 |
89081 |
ELF |
15365 |
210114 |
210114 |
210950 |
22330 |
33341 |
15384 |
13981 |
91447 |
PJW-32 |
15365 |
210114 |
210114 |
210950 |
22330 |
33341 |
15384 |
13981 |
91447 |
CrapWow |
871 |
888 |
833 |
852 |
336398 |
683930 |
898 |
871 |
128193 |
Adler |
3953 |
3953 |
3953 |
3953 |
2820 |
2567 |
3922 |
1840427 |
233194 |
BP |
1107319 |
1198700 |
2724548 |
2724563 |
1107368 |
1107368 |
1107640 |
1107656 |
1523145 |
Проведем еще один тест, правда вне конкурса. Тестовый набор - упорядоченные по возрастанию числа в десятичной системе исчисления. Очевидно, что здесь простые алгоритмы, основанные на математических вычислениях, покажут идеальные результаты. Наши алгоритмы не зависимы от типа исходного материала и покажут примерно те же результаты, что и на осмысленных текстах с небольшим допуском. Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
maBKDR |
0 |
0 |
0 |
0 |
83 |
162 |
0 |
357 |
75 |
crc32 |
0 |
0 |
0 |
0 |
428 |
414 |
0 |
419 |
158 |
LY |
0 |
0 |
0 |
0 |
831 |
1704 |
0 |
854 |
424 |
x17 |
0 |
0 |
0 |
0 |
838 |
1651 |
0 |
1128 |
452 |
BKDR |
0 |
0 |
0 |
0 |
868 |
1716 |
0 |
1129 |
464 |
Murmur2 |
415 |
798 |
876 |
835 |
866 |
1153 |
299 |
815 |
757 |
maPrime2a |
816 |
792 |
749 |
751 |
964 |
755 |
834 |
801 |
808 |
maPrime2b |
816 |
792 |
749 |
751 |
964 |
755 |
834 |
801 |
808 |
maPrime2 |
792 |
799 |
805 |
856 |
864 |
892 |
789 |
890 |
836 |
MaHash8 |
811 |
821 |
850 |
863 |
826 |
904 |
868 |
831 |
847 |
MaHash2 |
875 |
859 |
807 |
845 |
795 |
927 |
857 |
831 |
850 |
MaHashMR1 |
814 |
820 |
888 |
823 |
889 |
898 |
805 |
860 |
850 |
maPrime2d |
818 |
884 |
915 |
839 |
878 |
814 |
825 |
851 |
853 |
maPrime2c |
830 |
860 |
841 |
898 |
867 |
852 |
801 |
913 |
858 |
Murmur2AM |
854 |
819 |
854 |
880 |
874 |
922 |
859 |
828 |
861 |
Lookup3 |
847 |
877 |
871 |
880 |
898 |
823 |
859 |
857 |
864 |
MaHash3 |
837 |
913 |
915 |
872 |
871 |
860 |
818 |
827 |
864 |
maPrime |
832 |
906 |
880 |
941 |
864 |
865 |
808 |
826 |
865 |
MaHash11 |
870 |
877 |
879 |
840 |
908 |
849 |
880 |
849 |
869 |
MaHash5 |
877 |
851 |
871 |
835 |
880 |
886 |
883 |
886 |
871 |
MaHash1 |
900 |
844 |
850 |
871 |
906 |
857 |
882 |
861 |
871 |
Murmur3 |
848 |
932 |
836 |
889 |
805 |
1049 |
835 |
835 |
879 |
Murmur2a |
818 |
822 |
801 |
887 |
833 |
1132 |
887 |
893 |
884 |
MaHash4 |
911 |
937 |
902 |
862 |
838 |
874 |
934 |
839 |
887 |
MaHash7 |
908 |
1221 |
2063 |
2435 |
849 |
890 |
1034 |
1053 |
1307 |
MaHash6 |
950 |
1220 |
2100 |
2374 |
878 |
942 |
1021 |
1056 |
1318 |
Rs |
445 |
446 |
387 |
417 |
836 |
6623 |
410 |
1340 |
1363 |
MaHash9 |
906 |
1261 |
2241 |
2585 |
914 |
898 |
1083 |
1041 |
1366 |
fnv1 |
462 |
462 |
462 |
462 |
2282 |
4771 |
863 |
1800 |
1446 |
MaHash |
855 |
1258 |
2545 |
2953 |
962 |
955 |
1077 |
1093 |
1462 |
fnv1a |
736 |
736 |
736 |
736 |
2326 |
4639 |
705 |
1761 |
1547 |
Faq6 |
1894 |
1894 |
1894 |
1894 |
905 |
876 |
2548 |
908 |
1602 |
OneAtTime |
1894 |
1894 |
1894 |
1894 |
905 |
876 |
2548 |
908 |
1602 |
MaHash10 |
1117 |
1796 |
3640 |
4310 |
1059 |
972 |
1180 |
1290 |
1921 |
Crap8 |
1134 |
1050 |
1071 |
1085 |
4760 |
4993 |
1379 |
812 |
2036 |
SBOX |
1470 |
1545 |
1539 |
1496 |
2643 |
4821 |
1465 |
2312 |
2161 |
fnv |
1492 |
1492 |
1492 |
1492 |
3916 |
7798 |
661 |
3571 |
2739 |
GoulburnHash |
5415 |
9583 |
22218 |
26387 |
5655 |
5608 |
6237 |
6489 |
10949 |
AP |
306 |
393 |
56190 |
394 |
403 |
29847 |
442 |
409 |
11048 |
Js |
17934 |
18820 |
20734 |
21219 |
920 |
914 |
14195 |
1053 |
11974 |
Dek |
0 |
0 |
0 |
0 |
153 |
0 |
290519 |
40 |
36339 |
ROT13 |
56171 |
56171 |
56190 |
56203 |
40601 |
29847 |
21522 |
1880 |
39823 |
x31 |
0 |
0 |
0 |
0 |
53710 |
174137 |
0 |
402996 |
78855 |
CrapWow |
844 |
854 |
858 |
902 |
909 |
576574 |
874 |
421938 |
125469 |
djb |
0 |
0 |
0 |
0 |
894 |
1714 |
0 |
1214544 |
152144 |
SuperFastHash |
1302258 |
385692 |
384714 |
384720 |
154768 |
11499 |
298119 |
1149 |
365365 |
Sdbm |
0 |
0 |
0 |
0 |
269853 |
636087 |
0 |
2389609 |
411944 |
Elf |
0 |
1359899 |
1359899 |
1043099 |
1162284 |
2336423 |
142630 |
2672745 |
1259622 |
PJW-32 |
0 |
1359899 |
1359899 |
1043099 |
1162284 |
2336423 |
142630 |
2672745 |
1259622 |
Novak |
2562948 |
2562948 |
2562948 |
2562948 |
2507396 |
2507342 |
2570635 |
292643 |
2266226 |
Fletcher |
2603160 |
2431144 |
2431144 |
2431144 |
2574298 |
2574299 |
2592294 |
2717699 |
2544398 |
bp |
2625299 |
2716199 |
2726289 |
2726298 |
2626289 |
2626299 |
2635299 |
2636289 |
2664783 |
Adler |
2717856 |
2717856 |
2717856 |
2717856 |
2717856 |
2717856 |
2717856 |
2726054 |
2718881 |
Опять внеконкурсный тест. Тестовый набор - упорядоченные по возрастанию строки равной длины (128 символов), имеющие множество частичных совпадений. Набор символов - это латинский алфавит и цифры в десятичной системе исчисления. Такой тест не будет однозначно сложным, поскольку здесь не учитывается проблема появления коллизий при увеличении строки, от хэш-функции требуется лишь для разных текстов равной длины вычислить уникальное значение. Совпадения будут, но их будет меньше. Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
MaHash3 |
842 |
840 |
789 |
907 |
883 |
879 |
826 |
871 |
855 |
MaHash4 |
881 |
824 |
835 |
885 |
898 |
846 |
818 |
865 |
857 |
lookup3 |
903 |
829 |
865 |
838 |
847 |
834 |
910 |
858 |
861 |
Murmur2AM |
863 |
863 |
863 |
863 |
880 |
860 |
871 |
831 |
862 |
maPrime2d |
860 |
860 |
860 |
860 |
823 |
872 |
898 |
878 |
864 |
MaHash5 |
846 |
872 |
867 |
857 |
876 |
881 |
864 |
865 |
866 |
MaHash1 |
811 |
907 |
869 |
803 |
873 |
839 |
909 |
918 |
866 |
faq6 |
878 |
878 |
878 |
878 |
846 |
842 |
870 |
884 |
869 |
OneAtTime |
878 |
878 |
878 |
878 |
846 |
842 |
870 |
884 |
869 |
MaHash11 |
891 |
912 |
837 |
842 |
955 |
840 |
877 |
811 |
871 |
maHashMR1 |
862 |
850 |
846 |
869 |
858 |
898 |
911 |
874 |
871 |
MaHash2 |
843 |
930 |
840 |
855 |
881 |
912 |
849 |
867 |
872 |
crc32 |
884 |
884 |
884 |
884 |
884 |
884 |
866 |
872 |
880 |
MaHash8 |
894 |
899 |
923 |
859 |
884 |
918 |
860 |
862 |
887 |
ROT13 |
891 |
916 |
999 |
1014 |
871 |
844 |
876 |
899 |
914 |
maPrime2a |
837 |
837 |
837 |
837 |
872 |
1753 |
892 |
902 |
971 |
maPrime2b |
837 |
837 |
837 |
837 |
872 |
1753 |
892 |
902 |
971 |
SuperFastHash |
942 |
1278 |
939 |
1231 |
1029 |
1010 |
933 |
980 |
1043 |
maPrime |
858 |
858 |
858 |
858 |
838 |
3816 |
869 |
876 |
1229 |
maPrime2 |
864 |
864 |
864 |
864 |
848 |
3868 |
823 |
850 |
1231 |
RS |
868 |
868 |
868 |
868 |
1673 |
3510 |
848 |
1696 |
1400 |
x17 |
879 |
879 |
879 |
879 |
1737 |
3413 |
859 |
1728 |
1407 |
DJB |
868 |
868 |
868 |
868 |
1745 |
3505 |
820 |
1792 |
1417 |
BKDR |
897 |
897 |
897 |
897 |
1750 |
3435 |
853 |
1827 |
1432 |
maBKDR |
897 |
897 |
897 |
897 |
1750 |
3435 |
853 |
1827 |
1432 |
LY |
950 |
950 |
950 |
950 |
1759 |
3478 |
868 |
1712 |
1452 |
Novak |
826 |
826 |
826 |
826 |
1699 |
3426 |
848 |
3406 |
1585 |
MaHash7 |
843 |
1464 |
3281 |
3766 |
856 |
859 |
830 |
875 |
1597 |
MaHash6 |
862 |
1500 |
3312 |
3832 |
899 |
859 |
909 |
873 |
1631 |
JS |
825 |
1456 |
3376 |
3938 |
845 |
877 |
887 |
874 |
1635 |
MaHash9 |
876 |
1464 |
3559 |
4029 |
857 |
879 |
854 |
886 |
1676 |
maPrime2c |
895 |
878 |
891 |
839 |
872 |
7541 |
872 |
852 |
1705 |
MaHash |
907 |
1645 |
4126 |
5024 |
842 |
910 |
899 |
915 |
1909 |
Murmur3 |
889 |
914 |
883 |
855 |
3983 |
7856 |
862 |
868 |
2139 |
FNV1 |
896 |
896 |
896 |
896 |
3808 |
7664 |
808 |
1713 |
2197 |
FNV1a |
856 |
856 |
856 |
856 |
3919 |
7861 |
888 |
1729 |
2228 |
Crap8 |
817 |
855 |
891 |
804 |
4742 |
8561 |
816 |
863 |
2294 |
MaHash10 |
891 |
2417 |
6251 |
7609 |
897 |
876 |
916 |
890 |
2593 |
SBOX |
1529 |
1598 |
1583 |
1542 |
4510 |
8370 |
1547 |
2219 |
2862 |
Murmur2a |
864 |
864 |
864 |
864 |
7336 |
14819 |
853 |
881 |
3418 |
Murmur2 |
870 |
854 |
888 |
920 |
7555 |
14878 |
844 |
888 |
3462 |
FNV |
934 |
934 |
934 |
934 |
7252 |
14889 |
836 |
3430 |
3768 |
x31 |
889 |
889 |
889 |
889 |
1748 |
3522 |
834 |
27516 |
4647 |
AP |
898 |
898 |
898 |
898 |
27869 |
27869 |
904 |
882 |
7640 |
SDBM |
824 |
824 |
824 |
824 |
1729 |
3478 |
842 |
54598 |
7993 |
Goulburn |
5196 |
9334 |
22060 |
26281 |
5036 |
5080 |
5272 |
5169 |
10429 |
ELF |
15334 |
209470 |
209470 |
210543 |
15894 |
15688 |
15313 |
15417 |
88391 |
PJW-32 |
15334 |
209470 |
209470 |
210543 |
15894 |
15688 |
15313 |
15417 |
88391 |
Fletcher |
873 |
873 |
873 |
873 |
873 |
873 |
873 |
2660763 |
333359 |
Adler |
155568 |
155568 |
155568 |
155568 |
155568 |
155568 |
155568 |
2722085 |
476383 |
CrapWow |
876 |
834 |
868 |
833 |
2726297 |
2726297 |
892 |
857 |
682219 |
DEK |
813 |
813 |
813 |
813 |
2726297 |
2726297 |
843 |
1845 |
682317 |
BP |
35615 |
849097 |
2726283 |
2726298 |
35615 |
35615 |
17201 |
17201 |
805366 |
Опятьспецифичный тест. Но распространенный. Здесь мы проверяем как наш алгоритм будет хэшировать IP адреса (в виде строк). Конечно, IP адрес версии четыре - это 32-разрядное число и его можно хранить как есть и соответственно сортировать и производить поиск очень удобно. Но этот тест интересен тем, что строки все будут примерно одной длины, имеют много совпадений и набор символов ограничен числами 0-9 и точкой. Найти тестовые материалы можно здесь. Результаты в виде электронной таблицы доступны здесь.
Алгоритм |
Коллизии в тесте A |
Коллизии в тесте B |
Коллизии в тесте C |
Коллизии в тесте D |
Коллизии в тесте E |
Коллизии в тесте F |
Коллизии в тесте G |
Коллизии в тесте H |
Коллизии, среднее |
AP |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
crc32 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
MaHash8v64 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
x17 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
420 |
53 |
BKDR |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1284 |
161 |
maBKDR |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1284 |
161 |
ROT13 |
0 |
0 |
60 |
117 |
1224 |
870 |
247 |
1431 |
494 |
maPrime |
754 |
754 |
754 |
754 |
855 |
838 |
857 |
879 |
806 |
Murmur2A |
893 |
798 |
798 |
868 |
891 |
829 |
795 |
881 |
844 |
Murmur2 |
880 |
800 |
784 |
898 |
849 |
891 |
824 |
850 |
847 |
Murmur2AM |
847 |
854 |
854 |
762 |
920 |
882 |
807 |
856 |
848 |
maPrime2d |
863 |
863 |
863 |
863 |
817 |
880 |
816 |
832 |
850 |
MaHash1 |
790 |
883 |
883 |
830 |
882 |
852 |
829 |
850 |
850 |
MaHash3 |
858 |
853 |
815 |
919 |
826 |
862 |
831 |
848 |
852 |
maPrime2c |
865 |
837 |
926 |
833 |
887 |
845 |
751 |
869 |
852 |
MaHash4 |
863 |
844 |
883 |
847 |
853 |
827 |
902 |
843 |
858 |
MaHash8 |
830 |
887 |
911 |
902 |
843 |
829 |
828 |
844 |
859 |
maHashMR1 |
833 |
820 |
903 |
873 |
836 |
884 |
933 |
842 |
866 |
lookup3 |
885 |
845 |
895 |
867 |
881 |
866 |
827 |
876 |
868 |
MaHash11 |
928 |
873 |
914 |
843 |
827 |
873 |
829 |
865 |
869 |
MaHash5 |
823 |
911 |
828 |
862 |
888 |
881 |
884 |
883 |
870 |
maPrime2 |
883 |
883 |
883 |
883 |
867 |
868 |
887 |
824 |
872 |
MaHash2 |
872 |
872 |
832 |
866 |
917 |
861 |
920 |
872 |
877 |
faq6 |
890 |
890 |
890 |
890 |
865 |
868 |
913 |
875 |
885 |
OneAtTime |
890 |
890 |
890 |
890 |
865 |
868 |
913 |
875 |
885 |
Murmur2M |
1364 |
842 |
930 |
858 |
846 |
827 |
912 |
814 |
924 |
Murmur3 |
812 |
864 |
843 |
868 |
912 |
875 |
1363 |
868 |
926 |
maPrime2a |
1369 |
1369 |
1369 |
1369 |
885 |
736 |
681 |
683 |
1058 |
maPrime2b |
1369 |
1369 |
1369 |
1369 |
885 |
736 |
681 |
683 |
1058 |
FNV1 |
1080 |
1080 |
1080 |
1080 |
2227 |
4564 |
930 |
1734 |
1722 |
FNV1a |
1108 |
1108 |
1108 |
1108 |
2333 |
4613 |
1073 |
1710 |
1770 |
MaHash6 |
1027 |
1444 |
3161 |
3879 |
911 |
944 |
2661 |
2588 |
2077 |
MaHash7 |
950 |
1462 |
3249 |
3893 |
960 |
995 |
2608 |
2662 |
2097 |
SBOX |
1572 |
1491 |
1517 |
1487 |
2874 |
4831 |
1558 |
2265 |
2199 |
MaHash9 |
934 |
1581 |
3492 |
4253 |
941 |
1005 |
2694 |
2773 |
2209 |
FNV |
736 |
736 |
736 |
736 |
3500 |
7166 |
810 |
3390 |
2226 |
MaHash |
1087 |
1975 |
4339 |
4951 |
932 |
991 |
3277 |
3246 |
2600 |
JS |
3620 |
4272 |
6278 |
6701 |
916 |
896 |
3045 |
2682 |
3551 |
MaHash10 |
1090 |
2609 |
6307 |
7603 |
1003 |
1016 |
5034 |
5108 |
3721 |
LY |
5740 |
5740 |
5740 |
5740 |
5740 |
5740 |
0 |
0 |
4305 |
Crap8 |
1723 |
1693 |
1670 |
1653 |
833 |
823 |
68751 |
823 |
9746 |
Goulburn |
5741 |
9987 |
22413 |
26734 |
5763 |
5547 |
17923 |
17707 |
13977 |
SuperFastHash |
20533 |
26937 |
21965 |
31937 |
979 |
1641 |
55851 |
974 |
20102 |
DJB |
0 |
0 |
0 |
0 |
0 |
1984 |
0 |
194327 |
24539 |
x31 |
0 |
0 |
0 |
0 |
3888 |
16776 |
6510 |
356070 |
47906 |
RS |
0 |
0 |
0 |
0 |
0 |
612 |
824 |
600319 |
75219 |
CrapWow |
39206 |
35814 |
35768 |
38757 |
16914 |
948 |
1254466 |
4347 |
178278 |
SDBM |
0 |
0 |
0 |
0 |
38648 |
180053 |
1080 |
1598364 |
227268 |
DEK |
253552 |
253552 |
253552 |
253552 |
253552 |
292720 |
548736 |
0 |
263652 |
Novak |
451364 |
451364 |
451364 |
451364 |
451364 |
451364 |
431483 |
4196 |
392983 |
ELF |
253884 |
1491098 |
1491098 |
1073498 |
1496649 |
2614453 |
1180553 |
2432140 |
1504172 |
PJW-32 |
253884 |
1491098 |
1491098 |
1073498 |
1496649 |
2614453 |
1180553 |
2432140 |
1504172 |
Fletcher |
2647939 |
2489172 |
2489172 |
2489172 |
2693041 |
2693041 |
2489172 |
2720961 |
2588959 |
Adler |
2721044 |
2721044 |
2721044 |
2721044 |
2721044 |
2721044 |
2721044 |
2726245 |
2721694 |
BP |
2725238 |
2726192 |
2726289 |
2726298 |
2725238 |
2725238 |
2726294 |
2726294 |
2725885 |
Итоги и выводы
Итак, к чему мы пришли? Результат тестирования - это не просто набор таблиц и сухой статистики, которая мало кому интересна сама по себе.
Что нам показали эти цифры?
Прежде всего то, что практически все популярные и широко используемые алгоритмы далеки от идеала. Практически все алгоритмы, за исключением crc32 (который хэшем не является), имеют некоторые конструктивные недостатки. Это особенно хорошо показали нам тесты групп E и F (где используются строки, состоящие из одинаковых блоков) и подобные. Именно всплески коллизий у популярных алгоритмов, которые вызваны особенностью их дизайна, позволили вырваться вперед моим алгоритмам - они пускай и не показывают эталонных результатов на простых текстах, но за счет большей устойчивости к столкновениям выдают хорошую статистику.
Из участников исследования - хэш-функций можно отметить алгоритмы lookup3 и faq6, которые показали себя очень достойно на всех тестах. Они не показали идеальных результатов, но и не давали всплесков, практически во всех экспериментах по усредненным значениям лишь немного отстали от победителей.
Автор алгоритмов семейства MurmurHash по результатам моего тестирования обратил внимание на неожиданные свойства своей функции. Недостаток, который выявил тест F заключается во всплеске коллизий функции MurmurHash2 на подобных наборах данных. Возможно, в скором времени автор предложит новый вариант своей функции, которая уже не содержит этот недостаток. В таком случае алгоритм (уже под новым именем) сможет значительно улучшить свои показатели.
Еще один момент - это выявленная перспективность (да и эффективность) использования таблиц замен. Табличная замена - очень быстрая операция. Их легко реализовать программно и аппаратно, а эффект использования такой функции позволяет пожертвовать незначительным снижением производительности. С помощью внедрения операций табличной подстановки был изменен дизайн некоторых алгоритмов и это дало плоды - число коллизий снизилось, были устранены всплески коллизий на проблемных тестах.
Ну, и использование счетчика блока как элемента вычисления хэш-функции. Оно оправдано, как показали некоторые тесты. Удалось решить некоторые проблемы функций BKDR и, что еще интереснее, MurmurHash.
Мнения специалистов
Посмотрим, что думают относительно моих функций независимые эксперты. Прежде всего, интересно взглянуть на тесты, который провел Peter Kankowski. Эти тесты оценивают функцию как со стороны производительности, так и со стороны числа коллизий на определенных наборах данных. По их результатам, MaHash8, MaHash4, MaHash11 имеют низкое число коллизий, но являются сравнительно медленными, поскольку выполняют большое количество операций на символ. MaPrime2c выглядит более интересно, что собственно тесты и показали.
Эксперт так же отметил, что MaHash8 медленнее, чем MaHash4, а она - медленнее, чем MaHash11, то есть улучшение качества хэширования достигается
за счёт усложнения и замедления функции. MaHash тем не менее могут быть полезны, когда операция доступа к данным занимает больше времени, чем в тесте. Например, при использовании хэширования в файловой системе или базе данных.
Провести эти тесты самостоятельно вы можете, используя инструментарий тестирования, который размещен на сайте автора.
Продолжение следует?
Низкое число коллизий - это хорошо. Но что насчет скорости, насчет произвдительности наших супер - мега - ультра - крутых алгоритмов? Проверим и это. Не прошло и три года, как мы провели некоторые тесты производительности простых хеш-фунций общего назначения, не отказывыясь и от контроля их качества (в плане числа коллизий).
|
|