2011-10-31 76 views
3

我做錯了,或者Android的JVM實現SHA1是痛苦的慢?我的代碼如下: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實現?

我玩過緩衝區大小 - 沒有顯着差異。

Traceview結果

所以它似乎是更新散列的瓶頸。

enter image description here

研究

這很有趣。當我嘗試2.3.2(SE Xperia)時,處理速度約爲12meg/sec。當我嘗試2.2(HTC Legend)時,速度比第一個設備還要慢。從2.3開始有什麼變化嗎?

+1

將註銷移出循環並再次測試 –

+0

以兆字節發生更改時打印消息的方式實施日誌記錄 - 結果相同(120kb/sec) – lstipakov

+0

基準測試什麼是讀取時間和什麼是散列時間,您可能會花費更多的時間閱讀,你認爲你是。還可以嘗試使用不同的緩衝區大小,增加它可以幫助很多,8k塊可能比卡上的文件系統塊小。 –

回答

3

根據我的基準測試,該代碼應該能夠輕鬆地執行比120 kb/s更好的方式(我在不同的硬件上運行,但仍然)。

如果您使用Traceview來分析代碼,那麼花在哪裏?如果瓶頸是FileInputStream.read(),想想:

  • 如果一些其他的應用程序使用的SD卡在同一時間,因爲你,像一個媒體索引應用程序什麼的。與其他應用程序共享帶寬將對應用程序的SD卡閱讀性能產生不利影響。
  • 如果SD卡本身就是問題。嘗試另一個SD卡或重新格式化你的。

如果瓶頸是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。具有android.security.MessageDigest天然SHA-1的實施方式)

更新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上看到類似的加速。

+0

我已添加追蹤結果。看起來瓶頸在於update()。 – lstipakov

+0

謝謝。請參閱最新的答案。 –

+0

如何使用android.security包?它似乎不屬於公共API。 – lstipakov