Reputation: 3238
Am I doing it wrong, or Android's JVM implementation of SHA1 is painfully slow? My code is below:
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);
}
and here is log:
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
which is about 100k / sec, for me it is unacceptable.
I am using physical device (LG P990, 2.2.2). Can I get better results with Java, or I have to look into JNI implementation?
I have played with buffer size - no significant difference.
So it seems the bottleneck is in updating hash.
That is interesting. When I have tried on 2.3.2 (SE Xperia), processing speed was about 12meg/sec. When I've tried on 2.2 (HTC Legend), the speed was even slower than at first device. Could it be so that something has been changed since 2.3?
Upvotes: 4
Views: 2093
Reputation: 10358
According to my benchmarks, that code should easily be able to perform way better than 120 kb/s (I'm running on different hardware, but still).
If you profile the code with Traceview, where is the time spent? If the bottleneck is FileInputStream.read(), think about:
If the bottleneck is MessageDigest.update() (which I doubt), I guess you do need to look into a JNI solution. For your information, the SHA-1 implementation already is in native code (see android_message_digest_sha1.cpp), but maybe you can gain a speedup by avoiding some native <-> Java copying.
Update 1 (Please ignore):
(Based on your profiling, the problem seems to be that you don't use Android's optimized android.security.MessageDigest
but instead java.security.MessageDigest
. Try android.security.MessageDigest
instead. Both Android 2.2 and 2.3 have native SHA-1 implementations of android.security.MessageDigest
.)
Update 2:
Sorry, I forgot about android.security.MessageDigest
being internal. I now realize that I was also using java.security.MessageDigest
in my benchmarking. I was running on Android 2.3 though, and it turns out the SHA-1 implementation of java.security.MessageDigest
in Android 2.3 is in native code as well, while that appearently is not the case on Android 2.2.
So the answer to your original question is: Yes, it is painfully slow in Android 2.2 due to a Java implementation but significantly faster in Android 2.3 due to an implementation in native code. You should see similar speedups on Android 2.2 if you use your own SHA-1 implementation in native code.
Upvotes: 4