Цикл через курсор 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 из цикла, они дороги, и вам нужно сделать их только один раз, а не для каждой строки.