2012-03-14 3 views
5

Я пишу библиотеку Java, которая должна вычислять хэши SHA-1. Во время общей задачи JVM тратит около 70% своего времени в sun.security.provider.SHA.implCompress, 10% в java.util.zip.Inflater.inflate и 2% в sun.security.provider.ByteArrayAccess.b2iBig64. (Согласно профилировщику NetBeans.)Maximal SHA-1 Советы по производительности хэша в Java

Я не могу найти правильные ключевые слова для поиска Google, чтобы получить соответствующие результаты. Я не очень хорошо разбираюсь в алгоритме хэширования SHA-1. Как я могу получить максимальную отдачу от SHA-1 MessageDigest? Есть ли определенный размер куска, который я должен переваривать, или несколько значений определенных размеров, которые я должен попробовать?

Чтобы ответить на некоторые вопросы, которые вы думаете о выяснении:

  • Да, я переваривания, как прочитать файлы (MessageDigest.update), так что байты только переваривают один раз.
  • Сборники SHA-1 используются в качестве контрольных сумм, как правило, для файлов, которые должны быть zlib/завышены.
  • Нет, я не могу использовать другой хеш.
  • Да, я знаю, что zlib уже использует контрольные суммы, но внешние требования определяют использование хэшей SHA-1 поверх этого. Я не могу придумать вескую причину, почему (+1, если вы можете) :-)
+2

Если это IO на вашем локальном компьютере, который должен выполнить эту работу, я предлагаю инвестировать в SSD-диск, так как я подозреваю, что на самом деле чтение файлов с жесткого диска является узким местом здесь. –

+0

Я уже сделал все возможное, чтобы оптимизировать ввод-вывод. Я уже рассмотрел различные оптимизации IO, и профайлер говорит, что IO занимает столько же времени, сколько и переваривание.Я уверен, что я не могу сделать ничего лучше с IO –

+2

Java медленнее по сравнению с C/C++, но в некоторых задачах это немного быстрее. Если у вас есть доступ к реализации вашего алгоритма на C/C++, выполните сравнение. Если java значительно медленнее, возможно, есть возможности для улучшения, но если они почти равны, вероятно, есть небольшие шансы на улучшение. (Я сделал сравнение с C и Ds, когда у меня была куча математики, и оказалось, что моя версия java была самой быстрой). –

ответ

1

SHA-1 имеет размер блока 64 байта, поэтому кратким из них, вероятно, лучше всего; иначе реализация должна будет скопировать частичные блоки в буферы.

Вы работаете на многоядерном компьютере? Вы можете запустить декомпрессию zlib и хеширование SHA-1 в отдельных потоках, используя что-то вроде java.util.concurrent.SynchronousQueue, чтобы передать каждый распакованный 64-байтовый блок из одного потока в другой. Таким образом, у вас может быть один хеширование ядра одним блоком, в то время как другое ядро ​​распаковывает следующий блок.

(Вы можете попробовать одну из других реализаций BlockingQueue, которая имеет некоторую емкость, но я не думаю, что это очень помогло. Декомпрессия намного быстрее, чем хеширование, поэтому поток zlib быстро заполнил очередь, а затем придется ждать, чтобы поместить каждый новый блок, как и с SynchronousQueue.)

Я знаю, что вы сказали, что уже оптимизировали I/O, но используете ли вы асинхронный ввод-вывод? Для максимальной производительности вы не хотите хешировать один блок и , тогда попросите ОС прочитать следующий блок, вы хотите попросить ОС прочитать следующий блок, а затем хэш, который у вас уже есть, когда диск занят извлечением следующий. Однако ОС, вероятно, уже немного читает, так что это может не иметь большого значения.

Но помимо всего прочего, криптографическая хэш-функция является сложной вещью; это просто займет время, чтобы бежать. Возможно, вам нужен более быстрый компьютер. :-)

+0

Было бы неплохо, если бы они использовали некризисный хеш в качестве контрольной суммы вместо криптографической поверх CRC, используемой в zlib. Асинхронный ввод-вывод был бы хорошей идеей, если бы я не нацеливался на производительность моей библиотеки, а не на производительность этого конкретного теста на проверку большого количества файлов. Это заставило меня задуматься о том, как я могу сделать библиотеку, которую я разрабатываю, более многопоточную. Я думаю, я был просто удивлен, что вычисление контрольных сумм занимает больше времени, чем файлы ввода/вывода, что разработчики программ, которые используют файлы, с которыми я работаю, просто сделали странный выбор. –

+0

Ну, по-видимому, они хотят, чтобы дополнительное сопротивление столкновению было криптографическим хэш обеспечивает; иначе не было бы никакой добавленной стоимости над CRC, что zlib уже делает. – Wyzard

+0

И последовательный доступ к файлам не так уж и медленен на современных жестких дисках. У меня есть «зеленые» диски мощностью 5900 об/мин, которые в среднем превышают 100 МБ/с на всем диске, пик 150 МБ/с на краю. По сравнению с относительно медленным алгоритмом, таким как SHA-1, это неплохо. – Wyzard

0

Вы пытались переключить обработку файлов в файл с памятью? Производительность для тех, как правило, значительно быстрее, чем обычные IO и NIO.

+0

Сборники SHA-1 используются в качестве контрольных сумм, обычно для файлов, которые должны быть zlib/завышены. Фактически, я использую 'DirectByteBuffer', потому что большинство файлов нужно накачивать до того, как можно вычислить контрольную сумму. Рассматривая стек вызовов из профилировщика, механизм дайджеста использует метод, который при отправке буфера, у которого нет массива (не-кучного-буфера), фактически копирует содержимое прямого буфера в новую локальную, примитивный байтовый массив. Фактически, он даже оптимизирует этот примитивный буфер байтов на основе операционной системы и размера кэша L1 процессора. В зависимости от JVM. –

+0

Было бы неплохо, если бы JRE солнца предоставил дайджестер, который работал с MappedByteBuffers. Знаете ли вы, что я могу распространять в библиотеке? Было бы даже лучше, если java.util.zip работал с 'MappedByteBuffer'. Я имею в виду, что он уже работает в собственной памяти! Может быть, я поставлю RFE ... –

1

Возможно, вы можете позвонить в собственный код, написанный на C. Должна быть доступна тонна супер оптимизированных библиотек SHA1.

+0

Ewww ... это звучит как много работы. И я понятия не имею, может быть, мне просто нужно отправить правильные буферы в хранилище. Это действительно то, что я пытаюсь выяснить. –

Смежные вопросы