Utilizamos una carga de Google Guava LoadingCache para mapas de bits en una aplicación de Android. En la aplicación estoy ejecutando un hilo de dibujo, que pinta los mapas de bits en el caché de un lienzo. Si un mapa de bits específico no está en la memoria caché, no se dibuja para que ninguna carga pueda bloquear el hilo de dibujo.Mal rendimiento con Guava Cache en Android
Sin embargo, la pintura produce un tartamudeo visual y la velocidad de cuadros por segundo no es la que nos gustaría. Me clavé en el método getIfPresent()
de la memoria caché. Eso solo toma más del 20% del tiempo total de CPU de las aplicaciones. En getIfPresent()
LocalCache$Segment.get()
se hace cargo del 80% del tiempo:
Tenga en cuenta, esto es sólo una búsqueda de un mapa de bits ya presente. Nunca ocurrirá una carga en get()
. Pensé que habría una sobrecarga de contabilidad en get()
para la cola LRU que decide qué desalojo se lleva a cabo si el segmento está lleno. Pero esto es al menos un orden de magnitud más lento de lo que me daría un Key-Lookup
en LRU-LinkedHashmap.get()
.
Usamos un caché para obtener búsquedas rápidas si un elemento está en el caché, si la búsqueda es lenta, no tiene sentido almacenarlo en caché. También probé getAllPresent(a)
y asMap()
pero da el mismo rendimiento.
versión de la Biblioteca es: guayaba-11.0.1.jar
LoadingCache se define como sigue:
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);
}
});
Mis preguntas son:
- lo uso ¿incorrecto?
- ¿Su implementación no es compatible con Android?
- ¿Echaba de menos una opción de configuración?
- ¿Es este un problema conocido con la caché en la que se está trabajando?
Actualización:
Después de cerca de 100 cuadros pintados los CacheStats son:
I/System.out(6989): CacheStats{hitCount=11992, missCount=97,
loadSuccessCount=77, loadExceptionCount=0, totalLoadTime=1402984624, evictionCount=0}
Después de eso misscount se mantiene básicamente los mismos que los incrementos HitCount. En este caso, el caché es lo suficientemente grande para que las cargas sucedan escasamente, pero getIfPresent es lento, no obstante.
Por favor, no negrita cada dos frases; era difícil de leer, así que envié una edición para eliminarla. – simchona
Gracias, simchona por editarlo para hacerlo mejor legible. – user643011
¿Podría publicar los resultados de 'tiles.cacheStats()'? –