Android SHA1 мучительно медленный - PullRequest
3 голосов
/ 31 октября 2011

Я делаю это неправильно, или реализация JVM в Android для SHA1 мучительно медленная?Мой код ниже:

in = new FileInputStream("/mnt/sdcard/200mb");
MessageDigest digester = MessageDigest.getInstance("sha1");
byte[] bytes = new byte[8192];
int byteCount;
int total = 0;
while ((byteCount = in.read(bytes)) > 0) {
    total += byteCount;
    digester.update(bytes, 0, byteCount);
    Log.d("sha", "processed " + total);
}    

и вот журнал:

10-31 13:59:53.790 D/sha     ( 3386): processed 4931584
10-31 13:59:54.790 D/sha     ( 3386): processed 5054464
10-31 13:59:55.780 D/sha     ( 3386): processed 5177344

, что составляет около 100k / сек, для меня это неприемлемо.

Я используюфизическое устройство (LG P990, 2.2.2).Могу ли я получить лучшие результаты с Java, или мне нужно изучить реализацию JNI?

Я играл с размером буфера - без существенной разницы.

Результаты трассировки

Так чтоКажется, узкое место в обновлении хэша.

enter image description here

Исследования

Это интересно.Когда я попробовал на 2.3.2 (SE Xperia), скорость обработки была около 12 мг / сек.Когда я пробовал на 2.2 (HTC Legend), скорость была даже медленнее, чем на первом устройстве.Может ли быть так, что что-то изменилось с 2.3?

1 Ответ

3 голосов
/ 31 октября 2011

Согласно моим тестам, этот код легко может работать лучше, чем 120 кбит / с (я работаю на другом оборудовании, но все же).

Если вы профилируете код с помощью Traceview , где будет потрачено время? Если узким местом является FileInputStream.read (), подумайте о:

  • если какое-то другое приложение использует sdcard одновременно с вами, например приложение для индексации мультимедиа или что-то еще. Совместное использование полосы пропускания с каким-либо другим приложением отрицательно скажется на производительности чтения sdcard вашего приложения.
  • Если проблема связана с самой SD-картой. Попробуйте другой sdcard или переформатируйте тот, который у вас есть.

Если узким местом является MessageDigest.update () (в чем я сомневаюсь), я полагаю, вам действительно нужно искать решение JNI. К вашему сведению, реализация SHA-1 уже реализована в собственном коде (см. android_message_digest_sha1.cpp ), но, возможно, вы можете получить ускорение, избегая некоторого собственного <-> Java-копирования.

Обновление 1 (пожалуйста, игнорируйте):

(Судя по вашему профилированию, проблема заключается в том, что вы используете не оптимизированный для Android android.security.MessageDigest, а вместо этого java.security.MessageDigest. Попробуйте вместо него android.security.MessageDigest. И Android 2.2, и 2.3 имеют собственные реализации SHA-1 android.security.MessageDigest.)

Обновление 2:

Извините, я забыл о том, что android.security.MessageDigest является внутренним. Теперь я понимаю, что я также использовал java.security.MessageDigest в своем тесте производительности. Хотя я работал на Android 2.3, и оказалось, что реализация SHA-1 java.security.MessageDigest в Android 2.3 также написана на нативном коде, хотя на Android 2.2 это явно не так.

Таким образом, ответ на ваш первоначальный вопрос таков: Да, он мучительно медленный в Android 2.2 из-за реализации Java, но значительно быстрее в Android 2.3 из-за реализации в нативном коде. Вы должны увидеть аналогичные ускорения на Android 2.2, если вы используете свою собственную реализацию SHA-1 в собственном коде.

...