在我的应用程序中,我从服务器获取一些数据,在反序列化(从 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();
}
我测量的内容:
方法#1:
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/