我在Android应用程序上使用SQLite
数据库,我写的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 ms (在Nexus S
上)。我发现这是很多时间。而我不明白的是,大部分时间都花在第一次迭代上,如日志中所示:
D / FeedsProviderHelper(5800):此循环光标迭代采用:1726 ms。
D / FeedsProviderHelper(5800):此循环光标迭代采用:3 ms。
D / FeedsProviderHelper(5800):此循环光标迭代耗时:2 ms。
D / FeedsProviderHelper(5800):此循环光标迭代采用:3 ms。
D / FeedsProviderHelper(5800):此循环光标迭代耗时:2 ms。
D / FeedsProviderHelper(5800):此循环光标迭代采用:3 ms。
D / FeedsProviderHelper(5800):此循环光标迭代采用:3 ms。
D / FeedsProviderHelper(5800):此循环光标迭代耗时:2 ms。
D / FeedsProviderHelper(5800):此循环光标迭代采用:0 ms。
D / FeedsProviderHelper(5800):此循环光标迭代耗时:5毫秒。
D / FeedsProviderHelper(5800):此循环光标迭代采用:1 ms。
D / FeedsProviderHelper(5800):此循环光标迭代采用:1 ms。
D / FeedsProviderHelper(5800):此循环光标迭代耗时:5毫秒。
D / FeedsProviderHelper(5800):此循环光标迭代采用:1 ms。
D / FeedsProviderHelper(5800):此循环光标迭代采用:1 ms。
D / FeedsProviderHelper(5800):此循环光标迭代采用:1 ms。
D / FeedsProviderHelper(5800):通过整个游标循环: 1770毫秒。
所以我的问题是:
这是正常的吗?如果是,为什么?如果没有,我做错了什么?有没有更快的方法对SQLite数据库进行selectAll
?
谢谢!
修改
我将@ getColumnIndex
调用排除在@superfell建议的循环之外,现在我以平均 1500ms 运行getAll
方法。在我看来,它更快但不够快(再次)!
答案 0 :(得分:9)
你应该做的第一件事就是把getColumnIndex调用带出循环,它们很昂贵,你只需要做一次,而不是每一行。
答案 1 :(得分:3)
这是正常的吗?
不确定
如果是,为什么?
磁盘I / O价格昂贵,尤其是在闪存上。查询本身正在针对Cursor
的第一个实际请求上执行,这就是为什么您的第一次“迭代”花费的时间要长得多。
对SQLite数据库执行selectAll的更快方法是什么?
首先,您没有针对SQLite数据库执行“selectAll”。你正在对内容提供商进行“selectAll”。
使用Traceview准确确定您的时间占用时间,并相应地调整您的应用程序。例如,您可能会发现,首先不将数据从Cursor
复制到POJO列表中会更有意义。