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