【问题标题】:Android SHA1 is painfully slowAndroid SHA1 非常慢
【发布时间】:2011-11-01 18:00:42
【问题描述】:

是我做错了,还是 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/秒,对我来说是不可接受的。

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

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

跟踪查看结果

看来瓶颈在于更新哈希。

研究

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

【问题讨论】:

  • 将日志移出循环并再次测试
  • 以一种在兆字节发生变化时打印消息的方式实现日志记录 - 结果相同(120kb/秒)
  • 对什么是阅读时间和什么是哈希时间进行基准测试,您可能会花更多的时间阅读您认为的阅读时间。还可以尝试使用不同的缓冲区大小,增加它可能会有很大帮助,8k 块可能比你卡上的文件系统块小。
  • 添加了 traceview 结果。我玩过缓冲区大小 - 没有显着差异。
  • 在 iOS 上,我每秒可以获得接近 10m 的哈希值,这是在 SHA256 环境中......使用三星 Galaxy S5 我看到每秒大约 150k 的哈希值。老实说,iOS 和 Android 之间的性能差异令人尴尬。

标签: java android performance java-native-interface sha


【解决方案1】:

根据我的基准,该代码应该能够轻松地以超过 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 实现987654326@.)

更新 2:

抱歉,我忘了 android.security.MessageDigest 是内部人员。我现在意识到我也在我的基准测试中使用了java.security.MessageDigest。虽然我在 Android 2.3 上运行,但事实证明,Android 2.3 中 java.security.MessageDigest 的 SHA-1 实现也在本机代码中,而在 Android 2.2 上显然不是这种情况。

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

【讨论】:

  • 我添加了跟踪结果。似乎瓶颈在 update() 中。
  • 如何使用 android.security 包?它似乎不是公共 API 的一部分。
猜你喜欢
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
相关资源
最近更新 更多