Мы используем загрузку Google Guava LoadCache для растровых изображений в приложении для Android. В приложении я запускаю рисунок Thread, который рисует растровые изображения в кеше на Canvas. Если конкретное растровое изображение отсутствует в кеше, оно не получается нарисованным, так что никакая загрузка никогда не блокирует рисование Thread.
Тем не менее, картина приводит к визуальному заиканию, а скорость кадров в секунду - это не то, как мы хотели бы. Я прибил его к getIfPresent()
кеша. Только это занимает более 20% от общего времени процессора. В getIfPresent()
LocalCache$Segment.get()
занимает более 80% времени:
Имейте в виду, что это всего лишь просмотр уже существующего растрового изображения. В get()
никогда не будет нагрузки. Я полагал, что в get()
для очереди LRU будет выполняться служебная операция, которая решает, какое выселение происходит, если сегмент заполнен. Но это по крайней мере на порядок медленнее того, что Key-Lookup
в LRU-LinkedHashmap.get()
даст мне.
Мы используем кеш для быстрого поиска, если элемент находится в кеше, если поиск медленный, нет смысла его кэшировать. Я также попробовал getAllPresent(a)
и asMap()
но он дает равную производительность.
Версия библиотеки: guava-11.0.1.jar
LoadCache определяется следующим образом:
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);
}
});
Мои вопросы:
- Я использую это неправильно?
- Является ли она неприменимой для Android?
- Я пропустил вариант конфигурации?
- Это известная проблема с работающим кэшем?
Обновить:
После примерно 100 кадров, нарисованных CacheStats:
I/System.out( 6989): CacheStats{hitCount=11992, missCount=97,
loadSuccessCount=77, loadExceptionCount=0, totalLoadTime=1402984624, evictionCount=0}
После этого missCount остается в основном таким же, как приращения hitCount. В этом случае кеш достаточно велик, чтобы нагрузки случались редко, но getIfPresent медленнее.