В процессе поиска дубликатов в моих 2 терабайтах изображений, хранящихся на жестком диске, я был удивлен длительным временем работы инструментов fslint и fslint-gui.
Поэтому я проанализировал внутреннюю часть основного инструмента findup, который реализован в виде очень хорошо написанного и документированного сценария оболочки с использованием сверхдлинного канала.По сути, это основано на поиске и хешировании (MD5 и SHA1).Автор заявляет, что это было быстрее, чем любая другая альтернатива, в которую я не мог поверить.Поэтому я обнаружил Обнаружение дублирующихся файлов , где тема довольно быстро скользила в сторону хеширования и сравнения хешей, что, на мой взгляд, не самый лучший и самый быстрый способ.
Так что обычный алгоритм работает следующим образом:
- создать отсортированный список всех файлов (путь, размер, идентификатор)
- групповые файлы с одинаковым размером
- вычислить хэш всех файловс одинаковым размером и сравните хэши
- имеет одинаковые средства идентичные файлы - найден дубликат
Иногда скорость увеличивается, сначала используя более быстрый алгоритм хеширования (например, md5) сДля большей вероятности столкновения и второго, если хеш-код одинаков, используйте второй более медленный, но менее похожий на столкновение алгоритм, чтобы доказать дубликаты.Другим улучшением является сначала хэширование небольшого фрагмента для сортировки совершенно разных файлов.
Поэтому у меня сложилось мнение, что эта схема разбита на два разных измерения:
- дубликатыкандидаты снова читаются с медленного жесткого диска (первый блок) и снова (полный md5) и снова (sha1)
- , используя вместо этого хэш, просто сравнивая файлы побайтно, мы вводим (низкую) вероятностьложный отрицательный
- вычисление хеша намного медленнее, чем просто побайтное сравнение
Я нашел одно (Windows) приложение, которое заявляет, что оно быстрое, если не использовать это общее хешированиесхема.
Я совершенно не прав с моими идеями и мнением?
[Обновить]
Кажется, есть мнение, что хеширование может быть быстрее, чем сравнение.Но это, похоже, заблуждение из общего использования «хеш-таблиц ускоряет вещи».Но для создания хэша файла в первый раз файлы должны быть прочитаны полностью побайтно.Так что с одной стороны есть побайтовое сравнение, которое сравнивает только столько байтов каждой функции-дубликата-кандидата до первой отличающейся позиции.И есть хеш-функция, которая генерирует ID из такого количества байтов - скажем, первые 10 Кбайт терабайта или полный терабайт, если первые 10 Кб совпадают.Таким образом, в предположении, что у меня обычно нет готовой вычисляемой и автоматически обновляемой таблицы всех хэшей файлов, мне нужно вычислить хэш и прочитать каждый байт кандидатов-дубликатов.Для побитового сравнения не нужно этого делать.
[Обновление 2]
У меня есть первый ответ, который снова идет в направлении: "Хэши, как правило, являютсяхорошая идея "и из этого (не так уж и неправильно) думать, пытаясь рационализировать использование хэшей с (ИМХО) неправильными аргументами.«Хэши лучше или быстрее, потому что вы можете использовать их позже» - не вопрос.«Предполагая, что многие (скажем, n) файлы имеют одинаковый размер, чтобы найти дубликаты, вам нужно выполнить n * (n-1) / 2 сравнения, чтобы проверить их попарно все друг против друга. Используя сильные хэши,вам нужно будет хэшировать каждый из них только один раз, что даст вам n хешей. "перекошен в пользу хешей и неправильных (ИМХО) тоже.Почему я не могу просто прочитать блок из каждого файла одинакового размера и сравнить его в памяти?Если мне нужно сравнить 100 файлов, я открываю 100 файловых дескрипторов и считываю блок из каждого параллельно, а затем выполняю сравнение в памяти.Это выглядит намного быстрее, чем обновлять один или несколько сложных алгоритмов медленного хэширования с этими 100 файлами.
[Обновление 3]
Учитывая очень большой уклон в пользу "всегда следует использовать хеш-функции, потому что они очень хороши!" Я прочитал некоторые вопросы о качестве хеша, например этот:
Какой алгоритм хеширования лучше всего подходит для уникальности и скорости? Он показывает, что обычные хеш-функции чаще вызывают коллизии, чем мы думаем, из-за плохого дизайна и дня рождения парадоксон . Тестовый набор содержал: «Список из 216 553 английских слов (в нижнем регистре),
числа от «1» до «216553» (например, почтовые индексы и то, как плохой хэш уничтожил msn.com) и 216,553 «случайных» (т. е. типа 4 uuid) идентификаторов GUID ». Эти крошечные наборы данных производятся от 100 до почти 20 тыс. Столкновения. Поэтому тестирование миллионов файлов на (в) равенстве только на основе хэшей может быть не очень хорошей идеей.
Полагаю, мне нужно изменить 1 и заменить часть трубы md5 / sha1 на "cmp" и просто измерить время. Я держу вас в курсе.
[Обновление 3]
Спасибо за все отзывы. Медленно мы конвертируем. Фон - это то, что я наблюдал, когда fslints findup работал на моей машине md5, используя сотни изображений. Это заняло довольно много времени, и жесткий диск вращался, как ад Так что я бродил: «Какого черта этот сумасшедший инструмент думает об уничтожении моего жесткого диска и тратит огромное количество времени на сравнение байтов»: 1) дешевле на байт, чем любой алгоритм хэша или контрольной суммы и 2) с побайтовое сравнение Я могу вернуться к первому различию раньше, поэтому я сэкономлю массу времени, не тратя пропускную способность и время жесткого диска, читая полные файлы и вычисляя хеш-значения для полных файлов. Я все еще думаю, что это правда - но: я думаю, я не уловил, что сравнение 1: 1 (если (file_a [i]! = File_b [i]) возвращает 1;) может быть дешевле, чем хеширование на байт. Но сложное хеширование с помощью O (n) может выиграть, когда нужно сравнить больше файлов. Я поставил эту проблему в своем списке и планирую либо заменить часть md5 fslint в findup на cmp, либо улучшить pythons filecmp.py сравнить библиотеку, которая сравнивает только 2 файла одновременно с опцией для нескольких файлов и, возможно, версией md5hash.
Так что спасибо всем на данный момент.
И вообще ситуация такая, как вы, ребята, говорите: лучший способ (TM) полностью зависит от обстоятельств: жесткий диск и твердотельный накопитель, вероятность файлов одинаковой длины, дубликаты файлов, типичный размер файлов, производительность ЦП в сравнении с памятью в сравнении с диском, одинарная против Multicore и так далее. И я узнал, что мне следует чаще рассматривать хэши, но я разработчик встраиваемых систем, у которого в большинстве случаев очень ограниченные ресурсы; -)
Спасибо за все ваши усилия!
Marcel