Ant*_*neG 8 java android caching
我有一个应用程序,需要一个图片库(所有在Jpeg),并给出每个可能的对之间的相似性分数.在每个时间点,只能选择一对,并显示其相似性得分.
比较两个图像的算法具有一定的性能成本,因此比较一对需要几秒钟.
选择两张照片时:
示例(执行批处理时):http://db.tt/iD67SdCp
如果从未计算过分数,并且用户单击"分数",则该字段将切换为"计算...",然后将在计算完成时显示分数.
在分数字段中显示任何内容之前,当选择两对时,它们附加的位图将被发送到HashMap,以验证这两个位图是否已经有附加分数,在这种情况下它只是返回它.如果没有得分,则将作业发送到队列中.
要知道缓存中是否存在分数,我需要找到一种方法来对该对进行散列,以便我可以使用生成的密钥来查找缓存.这就是我的问题所在.有意义的是,两个Bitmap的散列应该很快.否则,我只是添加另一层计算.但是,我到目前为止散列两个Bitmap的方法是将它们发送到一个字节数组并获得它们的MD5校验和.像这样:
private Long getHashKey(Bitmap first, Bitmap second){
// TODO this IS costly, it render useless the cache optimization.
// also, it doesn't detect that comp(A,B) is the same as comp(B,A).
// much work to do here.
if(D) Profiling.start(TAG, "getHashKey");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
first.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] firstArray = stream.toByteArray();
second.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] secondArray = stream.toByteArray();
byte[] bitmapBuffer = new byte[firstArray.length + secondArray.length];
System.arraycopy(firstArray, 0, bitmapBuffer, 0, firstArray.length);
System.arraycopy(secondArray, 0, bitmapBuffer,
firstArray.length, secondArray.length);
Adler32 md5Hash = new Adler32();
md5Hash.update(bitmapBuffer);
long hashKey = md5Hash.getValue();
if(D) Profiling.stop();
return hashKey;
}
Run Code Online (Sandbox Code Playgroud)
但是,根据我所做的分析,这种方法运行大约需要53毫秒,这会导致UI中的延迟非常不愉快.在更详细的分析中,我发现大约95%的计算时间都是在compress方法中完成的.但是,我还没有找到另一种方法来获取支持位图的字节.
05-26 17:56:13.220: D/Profiling(9458): Profile for ImageCompareActivity.getHashKey:
05-26 17:56:13.220: D/Profiling(9458): > Count : 1996 calls
05-26 17:56:13.220: D/Profiling(9458): > Total runtime : 105765140 us
05-26 17:56:13.220: D/Profiling(9458): > Avg runtime : 52988 us
Run Code Online (Sandbox Code Playgroud)
我知道我对比特图进行散列的方法非常粗鲁.但是我不太了解散列函数,以及我可以用来唯一标识文件的Bitmap的哪些部分.我不想使用文件名或类似的东西,因为我想最终在数据库中发送这些位图.
[更新1] 我不知道Object.hashCode().现在,我修改了这样的方法:
private Integer getHashKey(Bitmap first, Bitmap second){
if(D) Profiling.start(TAG, "getHashKey");
Integer hashKey = new Integer(
1013 * (first.hashCode()) ^ 1009 * (second.hashCode()) );
if(D) Profiling.stop();
return hashKey;
}
Run Code Online (Sandbox Code Playgroud)
平均约18个我们.