gpt4 book ai didi

android - Android 中外部存储的 SQLite 性能不佳

转载 作者:IT王子 更新时间:2023-10-29 06:23:26 26 4
gpt4 key购买 nike

我正在使用外部存储将等待发送到服务器的事件存储在数据库中。

我发现插入记录时性能很差。我知道外部存储器可能很慢,但我想查看一些数字,所以我编写了一个小应用程序来测试它。

代码如下:

public static final int INSERTS = 100;

File dbFile = new File(Environment.getExternalStorageDirectory(), "test.sqlite3");
// File dbFile = new File(getFilesDir(), "test.sqlite3");
dbFile.delete();

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbFile, null);

db.execSQL("CREATE TABLE events (_id integer primary key autoincrement, event_type TEXT NOT NULL, timestamp BIGINT, data TEXT);");
db.execSQL("CREATE INDEX mainIndex ON events (event_type, timestamp ASC);");

InsertHelper helper = new InsertHelper(db, "events");

final int eventTypeCol = helper.getColumnIndex("event_type");
final int timestampCol = helper.getColumnIndex("timestamp");
final int dataCol = helper.getColumnIndex("data");

long start = System.currentTimeMillis();

String eventType = "foo", data = "bar";
long timestamp = 4711;

for(int i = 0; i < INSERTS; ++i) {
helper.prepareForInsert();
helper.bind(eventTypeCol, eventType);
helper.bind(timestampCol, timestamp);
helper.bind(dataCol, data);
helper.execute();
}

long end = System.currentTimeMillis();

Log.i("Test", String.format("InsertHelper, Speed: %d ms, Records per second: %.2f", (int)(end-start), 1000*(double)INSERTS/(double)(end-start)));

db.close();
dbFile.delete();

db = SQLiteDatabase.openOrCreateDatabase(dbFile, null);

db.execSQL("CREATE TABLE events (_id integer primary key autoincrement, event_type TEXT NOT NULL, timestamp BIGINT, data TEXT);");
db.execSQL("CREATE INDEX mainIndex ON events (event_type, timestamp ASC);");


start = System.currentTimeMillis();
ContentValues cv = new ContentValues();

for(int i = 0; i < INSERTS; ++i) {
cv.put("event_type", eventType);
cv.put("timestamp", timestamp);
cv.put("data", data);
db.insert("events", null, cv);
}

end = System.currentTimeMillis();

Log.i("Test", String.format("Normal, Speed: %d ms, Records per second: %.2f", end-start, 1000*(double)INSERTS/(double)(end-start)));

db.close();
dbFile.delete();

数据库与我的真实应用程序使用的数据库完全一样,我尝试删除索引但没有任何区别。

结果如下:

Nexus One, Internal memory      Method | Records | Time (ms) | Records per second-------------+---------+-----------+--------------------      Normal |   100   |    2072   |       48.26InsertHelper |   100   |    1662   |       60.17Nexus One, External memory:      Method | Records | Time (ms) | Records per second-------------+---------+-----------+--------------------      Normal |   100   |    7390   |       13.53InsertHelper |   100   |    7152   |       13.98Emulator, Internal memory:      Method | Records | Time (ms) | Records per second-------------+---------+-----------+--------------------      Normal |   100   |    1803   |       55.46InsertHelper |   100   |    3075   |       32.52Emulator, External memory:      Method | Records | Time (ms) | Records per second-------------+---------+-----------+--------------------      Normal |   100   |    5742   |       17.42InsertHelper |   100   |    7164   |       13.96 

如您所见,模拟器不可信任,InsertHelper如果有的话,应该会更快。
当然,这是意料之中的,测试主要是出于好奇。

然而,我担心的是使用外部存储器时手机性能不佳,我是否错过了 SQLiteDatabase 的一些关键方面?还是仅仅是为了让 SD 卡变慢?

我可以在我禁用的真实应用中添加 locking这没什么区别。

最佳答案

CommonsWare 的评论是正确的。对数据库性能产生重大影响的是使用事务。将您的插入循环包装在事务中。我不是 100% 确定它是否适用于 InsertHelper 但你可以尝试用这个替换你的 for 循环:

db.beginTransaction();
try {
for(int i = 0; i < INSERTS; ++i) {
helper.prepareForInsert();
helper.bind(eventTypeCol, eventType);
helper.bind(timestampCol, timestamp);
helper.bind(dataCol, data);
helper.execute();
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}

关于android - Android 中外部存储的 SQLite 性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6351808/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com