Estoy usando una base de datos SQLite
en una aplicación de Android y el método getAll
que he escrito toma demasiado tiempo en mi opinión.Looping a través de un cursor SQLite toma demasiado tiempo
Este es el código que estoy hablando:
public static List<Feed> getAll(Context context) {
List<Feed> feeds = new ArrayList<Feed>();
Uri allFeeds = Uri.parse(ContentProvidersUris.URL_CONTENT_PROVIDER_FEED);
long startQuery = BenchmarkUtils.start();
Cursor c = context.getContentResolver().query(allFeeds, null, null, null, "title desc");
long startCursor = BenchmarkUtils.start();
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
long startInsideCursor = BenchmarkUtils.start();
Feed feed = new Feed();
feed.setContent(c.getString(c.getColumnIndex(FeedsProvider.COL_WEBVIEW_CONTENT)));
feed.setDate(c.getString(c.getColumnIndex(FeedsProvider.COL_PUB_DATE)));
feed.setDescription(c.getString(c.getColumnIndex(FeedsProvider.COL_DESCRIPTION)));
feed.setName(c.getString(c.getColumnIndex(FeedsProvider.COL_FEED_NAME)));
Log.d(TAG, "This loop cursor iteration took : " + BenchmarkUtils.stop(startInsideCursor) + " ms.");
}
Log.d(TAG, "Looping through the ENTIRE Cursor took: " + BenchmarkUtils.stop(startCursor) + " ms.");
return feeds;
}
Como se puede ver también estoy midiendo el tiempo empleado por este bucle en cada iteración y resulta que se necesita un tiempo promedio de 1800 ms (en un Nexus S
). Encuentro que esto es mucho tiempo. Y lo que no entiendo es que la mayor parte de este tiempo se dedica en la primera iteración como se muestra en los registros:
D/FeedsProviderHelper (5800): Este cursor iteración del bucle tomó: 1726 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 3 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 2 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 3 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 2 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 3 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 3 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 2 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 0 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 5 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 5 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1 ms.
D/FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1 ms.
D/FeedsProviderHelper (5800): Looping a través del Cursor TOTAL tomó: 1770 ms.
Así que mis preguntas son:
¿Es normal? ¿Si es así por qué? Si no, ¿qué estoy haciendo mal? ¿Alguna forma más rápida de hacer un selectAll
contra la base de datos SQLite?
Gracias!
EDITAR
Tomé las getColumnIndex
llamadas fuera del circuito como @superfell sugirió, y ahora estoy ejecutando el método getAll
en un promedio 1.500 ms. ¡Es más rápido pero no lo suficientemente rápido en mi opinión (de nuevo)!
Si el proveedor de contenido está en el mismo proceso, o se está procesando de manera cruzada, el tiempo en esa primera fila parece muy extraño. – superfell
@superfell Mismo proceso. –