use*_*011 19 java android guava
我们在Android应用程序中使用加载Google Guava LoadingCache作为位图.在应用程序中,我正在运行一个绘图线程,它将缓存中的位图绘制到Canvas.如果特定位图不在缓存中,则不会绘制它,因此任何加载都不会阻止绘制线程.
然而,这种绘画导致视觉口吃,每秒帧速率不是我们想要的.我把它钉getIfPresent()在了缓存的方法上.仅此一项占应用总CPU时间的20%.在getIfPresent() LocalCache$Segment.get()需要的时间超过80%:

请记住,这只是一个已经存在的位图的查找.永远不会发生负担get().我认为get()LRU队列会有一个簿记开销,它决定了如果段已满就会发生哪些驱逐.但是,这是至少一个数量多么慢的顺序Key-Lookup中LRU-LinkedHashmap.get()会给我.
如果一个元素在缓存中,我们使用缓存来获得快速查找,如果查找很慢,则缓存它没有意义.我也尝试了getAllPresent(a),asMap()但它提供了相同的性能.
库版本是:guava-11.0.1.jar
LoadingCache定义如下:
LoadingCache<TileKey, Bitmap> tiles = CacheBuilder.newBuilder().maximumSize(100).build(new CacheLoader<TileKey,Bitmap>() {
@Override
public Bitmap load(TileKey tileKey) {
System.out.println("Loading in " + Thread.currentThread().getName() + " "
+ tileKey.x + "-" + tileKey.y);
final File[][] tileFiles = surfaceState.mapFile.getBuilding()
.getFloors().get(tileKey.floorid)
.getBackground(tileKey.zoomid).getTileFiles();
String tilePath = tileFiles[tileKey.y][tileKey.x].getAbsolutePath();
Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
return BitmapFactory.decodeFile(tilePath, options);
}
});
Run Code Online (Sandbox Code Playgroud)
我的问题是:
更新:
在绘制大约100帧后,CacheStats是:
I/System.out( 6989): CacheStats{hitCount=11992, missCount=97,
loadSuccessCount=77, loadExceptionCount=0, totalLoadTime=1402984624, evictionCount=0}
Run Code Online (Sandbox Code Playgroud)
之后,missCount基本上与hitCount增量保持一致.在这种情况下,缓存足够大,以便负载稀疏地发生,但getIfPresent仍然很慢.
Ben*_*nes 31
CacheBuilder是为服务器端缓存而设计的,其中并发性是主要关注点.因此,它会牺牲单线程和内存开销来换取更好的多线程行为.Android开发人员应该使用LruCache,LinkedHashMap或类似的单线程性能和内存是主要问题.将来可能会有concurrencyLevel = 0来指示需要轻量级,非并发缓存.
| 归档时间: |
|
| 查看次数: |
9426 次 |
| 最近记录: |