Цикл через курсор SQLite занимает слишком много времени

Я использую SQLite база данных на Android приложения и getAll метод, который я написал занимает слишком много времени на мой взгляд.

это код, о котором я говорю:

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;
}

как вы можете видеть, я также измеряю время, затраченное этим циклом на каждой итерации, и оказывается, что это занимает среднее время 1800 МС (на Nexus S). Я считаю, что это много времени. И что я не понимаю, что большую часть этого времени потрачено на первой итерации как показано в журналах:

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 1726 МС.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 3 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 2 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 3 мс.

D / FeedsProviderHelper( 5800): Эта итерация курсора цикла заняла: 2 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 3 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 3 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 2 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 0 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 5 ms.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 1 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 1 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 5 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 1 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 1 мс.

D / FeedsProviderHelper (5800): эта итерация курсора цикла заняла: 1 мс.

D / FeedsProviderHelper (5800): цикл через весь курсор взял: 1770 МС.

Итак, мои вопросы:

это нормально? Если да, то почему? Если нет, то что я делаю не так? Любой более быстрый способ сделать selectAll против базы данных SQLite?

спасибо!

редактировать

взял getColumnIndex вызовы из цикла как @superfell предложил, и теперь я запускаю getAll метод в среднем 1500 МС. Это быстрее, но недостаточно быстро, на мой взгляд (снова)!

2 ответов


это нормально?

конечно.

Если да, то почему?

дисковый ввод-вывод стоит дорого, особенно на flash. Сам запрос выполняется по вашему первому реальному запросу против Cursor, поэтому ваша первая "итерация" занимает значительно больше времени.

любой более быстрый способ сделать selectAll против базы данных SQLite?

во-первых, вы не делаете "selectAll" против SQLite база данных. Вы делаете "selectAll" против поставщика контента.

используйте Traceview, чтобы точно определить, где ваше время занимает, и настроить приложение соответственно. Например, вы можете обнаружить, что имеет смысл не копировать данные из Cursor в список POJOs в первую очередь.


первое, что вам нужно сделать, это взять вызовы getColumnIndex из цикла, они дороги, и вам нужно сделать их только один раз, а не для каждой строки.