gpt4 book ai didi

java - SQLite:哪种插入策略更好?一大批还是许多小批?

转载 作者:行者123 更新时间:2023-11-30 08:53:47 26 4
gpt4 key购买 nike

在我的应用程序中,我从我的服务器获取一些数据,并在反序列化(从 JSON 到对象)之后将这些对象放入我的数据库中。直到今天我才有方法:

for(int i=0; i<receivedJsonArray.length; i++)
Bean bean = new Bean();
//matching some parameters
//...
dao.putObject(bean);
}

我的 dao.putObject(Bean) 是这样的(我省略了一些东西,比如 try-catch block ,因为它们并不真正相关)。

 public void putObject(Bean bean){
sqliteDatabase.beginTransaction();
ContentValues values = new ContentValues();
values.put("something", bean.getSomething());
// ... some mapping
database.insert("table", null, values);
database.setTransactionSuccessful();
database.endTransaction();
}

正如您在这里看到的,每次我反序列化单个对象实例时,我都在进行新事务等等。但是,我觉得我使用了第二种方法中的一小部分内存。

Bean[] beans = new Bean[receivedJsonArray.length]; 
for(int i=0; i<receivedJsonArray.length; i++)
Bean bean = new Bean();
//matching some parameters
//...
beans[i] = bean;
}
dao.putObject(beans);

现在 dao.putObject(Bean...) 看起来像

 public void putObject(Bean... beans){
sqliteDatabase.beginTransaction();
for(int i=0; i<beans.length; i++){
ContentValues values = new ContentValues();
values.put("something", beans[i].getSomething());
// ... some mapping
database.insert("table", null, values);
}
database.setTransactionSuccessful();
database.endTransaction();
}

所以现在我想知道这两个中哪一个是处理大约 400-500 个对象的更好方法?我觉得开始和结束交易 400-500 次是一种不好的做法。另一方面,我为创建和保存相当大的数据集合感到难过。
我知道在我针对我的应用程序(Android 4.+)的设备中,这并不重要,因为我拥有高效的 CPU 和相当多的 RAM;但是我觉得这不是低效率代码的借口。

那么,你有什么建议呢?一个大批量,插入每个对象,或者可能尝试一次插入一堆(即)100 个对象?

最佳答案

我测量了时间,结果非常明确。

使用的 DAO 方法如下所示:

public void addObject(Bean ... beans) {
SQLiteDatabase database = dbHelper.openDatabase();
database.beginTransaction();
try{
for(int i=0; i<roomBeans.length; i++) {
ContentValues values = new ContentValues();
//putting stuff in values
database.insertWithOnConflict("table", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
database.setTransactionSuccessful();
}catch(SQLException e) {
Log.e(AppConstants.DEBUG_TAG, e.toString());
}finally {
database.endTransaction();
}
dbHelper.closeDatabase();
}

我测量的是什么:

方法一:

        DAO.deleteRows(); // so I'm inserting into an empty table
long time = new Date().getTime();
for(int i=0; i<objectsArray.length()*50; i++){
JSONArray entry = (JSONArray) objectsArray.get(i%objectsArray.length());

Bean bean = new Bean();
bean.setStuff(entry.getInt(0));
// and so on...
dao.addObject(bean);
}

long timeFinish = new Date().getTime();
long timeTotal = timeFinish - time;

方法 #2:

        DAO.deleteRows(); // so I'm inserting into an empty table
long time = new Date().getTime();
Bean[] beans = new Bean[objectsArray.length()*50];
for(int i=0; i<objectsArray.length()*50; i++){
JSONArray entry = (JSONArray) objectsArray.get(i%objectsArray.length());

Bean bean = new Bean();
bean.setStuff(entry.getInt(0));
// and so on...
beans[i] = bean;
}
dao.addObject(beans);
long timeFinish = new Date().getTime();
long timeTotal = timeFinish - time;

结果:

每种方法都经过了十次测试,以确保结果在某种程度上是可重现的。

方法 #1
timeTotal 值20628, 20964, 19699, 19380, 20299,20553, 19715, 18239, 20267, 18711
方法 #2
timeTotal 值1289, 1333, 1288, 1388, 1294,1393, 1344, 1334, 1376, 1360

总结:
这里的数字胜于 Eloquent 。我不知道如何检查此处使用的确切内存量,但即使我使用 1-2 MB 的 RAM(考虑到我使用的 Bean 的结构,这是 IMO 有点极端的预测)2 秒,也不会发生任何错误假设这个 Bean[] 数组是一个局部变量。离开方法的范围后,它应该很快被 GC 处理,每个人都应该高兴。这些结果可能也取决于表和数据本身的 SQL 逻辑。

如果您不同意我的观点,请随时发表评论。

关于java - SQLite:哪种插入策略更好?一大批还是许多小批?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29662479/

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