Bucle a través de un Cursor SQLite lleva demasiado tiempo

Estoy utilizando una SQLite datos SQLite en una aplicación de Android y el método getAll que he escrito toma demasiado tiempo en mi opinión.

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 que toma este bucle en cada iteración y resulta que toma un tiempo promedio de 1800 ms (en un Nexus S ). Me parece que esto es mucho tiempo. Y lo que no entiendo es que la mayor parte de este tiempo se gasta en la primera iteración como se muestra en los registros:

D / FeedsProviderHelper (5800): Esta iteración del cursor de 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): Bucle a través del Cursor ENTIRE tomó: 1770 ms.

Así que mis preguntas son:

¿Es normal? ¿Si es así por qué? Si no, ¿qué estoy haciendo mal? Cualquier forma más rápida de hacer un selectAll contra la base de datos SQLite?

¡Gracias!

EDITAR

Tomé las llamadas de getColumnIndex fuera del lazo como @superfell sugirió, y ahora estoy funcionando el método de getAll en un promedio 1500ms . Es más rápido pero no lo suficientemente rápido en mi opinión (de nuevo)!

¿Es normal?

Por supuesto.

¿Si es así por qué?

E / S de disco es cara, especialmente en flash. La consulta en sí se ejecuta en su primera solicitud real contra el Cursor , por lo que su primera "iteración" tarda mucho más.

Cualquier forma más rápida de hacer un selectAll contra la base de datos SQLite?

En primer lugar, no estás haciendo un "selectAll" contra una base de datos SQLite. Estás haciendo un "selectAll" contra un proveedor de contenido.

Utilice Traceview para determinar con precisión dónde se va a tomar su tiempo y sintonice su aplicación en consecuencia. Por ejemplo, podría encontrar que tiene más sentido no copiar datos de un Cursor en una lista de POJOs en primer lugar.

Lo primero que debe hacer es tomar las llamadas getColumnIndex fuera del bucle, son caras, y sólo es necesario hacerlas una vez, no para cada fila.

  • Eliminar todas las filas de tabla de la tabla de base de datos SQLite
  • Android cursor cómo obtener valores nulos de columnas
  • ¿Qué tipos de bases de datos están disponibles en Android?
  • Cursor finalizado sin cerrar antes () Android
  • ¿Puedo hacer que SQLiteDatabase se queje de los parámetros que faltan?
  • Obtener la distancia más corta desde un punto
  • Cómo implementar la función recursiva de sqlite3 en dispositivos Android
  • GreenDAO soporta múltiples relaciones entre tablas
  • ¿Por qué utilizar SQLiteOpenHelper sobre SQLiteDatabase?
  • Código de error SQLite 17
  • Android Studios: Android Device Manager no muestra archivos para Nougat 7.0 en el Explorador de archivos
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.