Jes*_*lle 5 sqlite android android-cursor
看起来android.database.Cursor.getColumnIndex(String)在行循环上应该是不变的。
但我看到大量代码在执行以下操作:
try (Cursor cursor = database.query(...)) {
while (cursor.moveToNext()) {
String aString = cursor.getString(cursor.getColumnIndex(aColumnName));
// ... other loop code and more repeated use of getColumnIndex()
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来很愚蠢而且浪费,除非 的结果getColumnIndex()确实会随着对cursor.moveToNext()-- 的调用而变化,并且这个调用应该被提升到循环之外,如下所示:
try (Cursor cursor = database.query(...)) {
int aStringIdx = cursor.getColumnIndex(aColumnName);
while (cursor.moveToNext()) {
String aString = cursor.getString(aStringIdx);
// ... other loop code
}
}
Run Code Online (Sandbox Code Playgroud)
或者在最坏的情况下(假设getColumnIndex()要求您位于有效的数据行上):
try (Cursor cursor = database.query(...)) {
if (cursor.moveToFirst()) {
int aStringIdx = cursor.getColumnIndex(aColumnName);
do {
String aString = cursor.getString(aStringIdx);
// ... other loop code
} while (cursor.moveToNext());
}
}
Run Code Online (Sandbox Code Playgroud)
那么这里的真实故事是什么呢?
我看到每次通过行循环都执行了 getColumnIndex 操作,这根本没有意义
也许是因为当我们执行查询时,我们收到一个SQLiteCursor实例,而不是 AbstractCursor。如果我们查看源代码,我们可以发现内部构建了一个chache:
@Override
public int getColumnIndex(String columnName) {
// Create mColumnNameMap on demand
if (mColumnNameMap == null) {
String[] columns = mColumns;
int columnCount = columns.length;
HashMap<String, Integer> map = new HashMap<String, Integer>(columnCount, 1);
for (int i = 0; i < columnCount; i++) {
map.put(columns[i], i);
}
mColumnNameMap = map;
}
//...
}
Run Code Online (Sandbox Code Playgroud)
另一方面,访问变量(如示例 2)比计算哈希键来获取索引要快。可能与表的大小相关。
编辑:在具有复杂查询的大表上进行测试,似乎改进接近 5%,在我的情况下不值得进行更改。一般来说,HashMap 缓存已经足够好了。
| 归档时间: |
|
| 查看次数: |
1031 次 |
| 最近记录: |