Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


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)!

  • Permiso de negación: esto requiere android.permission.INTERACT_ACROSS_USERS_FULL
  • ¿Por qué utilizar sqlite Database en Android?
  • Integración ormlite-4.9 con sqlcipher-2.08
  • Cómo insertar marca de tiempo en una columna de base de datos SQLite? Utilizando el tiempo de función ('ahora')?
  • Método SQLiteDatabase.query
  • Cómo convertir la matriz de bytes en Bitmap
  • Cómo probar la actualización de la base de datos sqlite antes de cargar la nueva versión de mi aplicación en la tienda de juegos en android
  • Búsqueda de Android con Fragmentos
  • 2 Solutions collect form web for “Bucle a través de un Cursor SQLite lleva demasiado tiempo”

    ¿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.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.