4

是我做错了,还是 Android 的 SHA1 JVM 实现非常缓慢?我的代码如下:

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 / sec,对我来说这是不可接受的。

我正在使用物理设备(LG P990、2.2.2)。我可以使用 Java 获得更好的结果,还是必须研究 JNI 实现?

我玩过缓冲区大小 - 没有显着差异。

跟踪查看结果

因此,瓶颈似乎在于更新哈希。

在此处输入图像描述

研究

这太有趣了。当我尝试 2.3.2 (SE Xperia) 时,处理速度约为 12meg/sec。当我尝试 2.2 (HTC Legend) 时,速度甚至比第一台设备还要慢。会不会是因为 2.3 之后发生了一些变化?

4

1 回答 1

4

根据我的基准测试,该代码应该能够轻松地以超过 120 kb/s 的速度执行(我在不同的硬件上运行,但仍然如此)。

如果您使用Traceview分析代码,那么花费的时间在哪里?如果瓶颈是 FileInputStream.read(),考虑一下:

  • 如果其他应用程序与您同时使用 sdcard,例如媒体索引应用程序或其他东西。与其他应用共享带宽会对应用的 sdcard 读取性能产生不利影响。
  • 如果sdcard本身是问题。尝试另一个 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 上运行,但事实证明,java.security.MessageDigestAndroid 2.3 中的 SHA-1 实现也在本机代码中,而在 Android 2.2 上似乎并非如此。

因此,您最初问题的答案是:是的,由于 Java 实现,它在 Android 2.2 中速度非常慢,但由于在本机代码中实现,在 Android 2.3 中速度要快得多。如果您在本机代码中使用自己的 SHA-1 实现,您应该会在 Android 2.2 上看到类似的加速。

于 2011-10-31T16:05:06.603 回答