2016-03-03 65 views
2

我想在Android应用程序中用SQLM替换SQLite。境界需要更多的时间进行读写SQLite

以下是如何,我试图做到这一点的伪代码:

//SQLite Insert 
public void deleteExistingAndInsertNewItemsInDb(ArrayList<Item> itemList, int userId) { 
    Log.d("REALM_TEST", "No. of Records :: " + itemList.size()); 
    long start; 
    if (itemList != null && itemList.size() > 0) { 
     start = System.nanoTime(); 
     initializeDb(); 
     db.beginTransaction(); 
     // delete existing items from the item list table for the provided userId 
     db.delete(DataBaseHelper.TABLE_NAME, DataBaseHelper.USER_ID + "=" + userId, null); 
     // insert new item list into local DB. 
     for(Item item : itemList) { 
      ContentValues contentValues = new ContentValues(); 
      contentValues.put(DataBaseHelper.COL1, item.getProperty1()); 
      contentValues.put(DataBaseHelper.COL2, item.getProperty2()); 
      ... 
      ... 
      contentValues.put(DataBaseHelper.COL50, item.getProperty50()); 
      // insert item details into local DB. 
      db.insert(DataBaseHelper.TABLE_NAME, null, contentValues); 
     } 
     db.setTransactionSuccessful(); 
     db.endTransaction(); 
     // close database. 
     closeDb(); 
     long sum = System.nanoTime() - start; 
     Log.d("REALM_TEST", "Sqlite Insert :: " + sum/1000000); 
    } 
} 


//SQLite Read 
public ArrayList<Item> getItemListFromDB(int userId){ 

    ArrayList<Item> itemList = new ArrayList<>(); 
    initializeDb(); 
    long start = System.nanoTime(); 
    Cursor cursor = db.query(DataBaseHelper.TABLE_NAME, DataBaseHelper.COLUMN_LIST, DataBaseHelper.USER_ID + "=" + userId, 
      null, null, null, null); 
    if(cursor != null) { 
     while(cursor.moveToNext()) { 
      Item item= new Item(); 
      item.setProperty1(cursor.getString(0)); 
      item.setProperty2(cursor.getString(1)); 
      ... 
      ... 
      ... 
      item.setProperty50(cursor.getString(50)); 

      itemList.add(item); 
     } 
    } 
    closeDb(); 
    sum = System.nanoTime()-start; 
    Log.d("REALM_TEST", "Sqlite read list :: " + sum/1000000 + "ms For " + itemList.size() + " records"); 
    return itemList; 
} 

//Realm Insert 
public void deleteExistingAndInsertNewItemsInRealm(ArrayList<Item> itemList, int userId) { 

    Realm realm = Realm.getInstance(Application.getContext()); 
    long start = System.nanoTime(); 
    //delete all objects 
    RealmResults<RealmItem> results = realm.where(RealmItem.class).findAll(); 
    realm.beginTransaction(); 
    results.clear(); 

    for (Item item : itemList) { 
     RealmItem realmItem = realm.createObject(RealmItem.class); 
     realmItem.setProperty1(item.getProperty1()); 
     realmItem.setProperty2(item.getProperty2()); 
     ... 
     ... 
     realmItem.setProperty50(item.getProperty50()); 
    } 
    realm.commitTransaction(); 
    long sum = System.nanoTime() - start; 
    Log.d("REALM_TEST", "Realm Insert :: " + sum/1000000); 
} 


//Realm Read 
public ArrayList<Item> getItemListFromRealm(int userId) { 

    ArrayList<Item> itemList = new ArrayList<>(); 
    Realm realm = Realm.getInstance(Application.getContext()); 
    long start = System.nanoTime(); 
    RealmResults<RealmItem> results = realm.where(RealItem.class) 
      .equalTo("USER_ID", userId).findAll(); 
    if(results != null) { 
     for (RealItem result: results) { 

      Item item= new Item(); 
      item.setProperty1(result.getProperty1()); 
      item.setProperty2(cursor.getProperty2()); 
      ... 
      ... 
      ... 
      item.setProperty50(cursor.getProperty50()); 

      itemList.add(item); 
     } 
    } 
    sum = System.nanoTime()-start; 
    Log.d("REALM_TEST", "Realm read list :: " + sum/1000000 + "ms For " + itemList.size() + " records"); 
    return itemList; 
} 

500项下面是读写时间以毫秒为秒:

+--------+-------+--------+-------+ 
| Write   | Read   | 
+--------+-------+--------+-------+ 
| Sqlite | Realm | Sqlite | Realm | 
| 247 | 382 | 142 | 222 | 
| 303 | 321 | 102 | 278 | 
| 263 | 303 | 134 | 240 | 
| 301 | 292 | 165 | 290 | 
+--------+-------+--------+-------+ 

我做错什么了吗?

更新:

我添加了一个工作示例here。写入时间与我的实际应用程序几乎相似。在这个例子中,阅读时间已经有所改善。

我在示例中使用单个数据类型字符串作为实际应用程序中数据类型的良好混合。

+1

上面并没有真正的编译,这让我们有点难以判断是否有更严重的错误。从快速浏览它看起来没问题,但请注意,您可以使用'Realm.copyFromRealm()'来获取RealmObject的副本,而不是手动执行它。如果你可以粘贴真实的代码来产生你得到的结果,在这里或者在Gist中,那么判断是否有什么错误会更容易。 –

+0

现在,我不想从'RealmItem'扩展原来的'Item',尽管如此,我会尝试做一个工作示例。 –

+0

@ChristianMelchior,我已经添加了一个工作示例[这里](https://github.com/rahul01/RealmTest.git)。写入时间与我的实际应用程序几乎相似。阅读时间在领域的例子中有所改善。我在示例中的所有属性中使用单个数据类型“String”,实际上它是一种很好的数据类型组合。 –

回答

1

你在这里写的测试看起来是正确的,所以你得到的数字对于它所运行的硬件可能相当准确。但是请注意,基准测试非常棘手,无法正确控制,并且受到许多不受控制的事情的影响(例如运行其他应用程序/传感器/ GC)。

一些指点,让你的境界代码更是低于,但请注意这不会提高你的基准测试结果只是使你的代码更容易阅读和维护:

1)https://github.com/rahul01/RealmTest/blob/master/RealmTest/app/src/main/java/com/test/realmtest/DataBase.java#L429-Lundefined

任何理由您是将所有数据复制到标准Java对象中? RealmObjects默认情况下是懒惰的,如果您实际上不需要使用全部50个字段,则性能会更好。如果您确实想要复制所有数据,请考虑使用Realm.copyFromRealm()。这会自动复制所有内容,因此您不必像现在那样手动复制它。

2)https://github.com/rahul01/RealmTest/blob/master/RealmTest/app/src/main/java/com/test/realmtest/DataBase.java#L359-L429

不用手动填写所有字段,你可以使用Realm.copyToRealm()代替这将是一个1班轮而不是50行,你不必维护它,如果字段改变。

3) https://github.com/rahul01/RealmTest/blob/master/RealmTest/app/src/main/java/com/test/realmtest/DataBase.java#L354-L359

对于使用Realm.clear(RealmItem.class)删除特定类型的所有项目比较快。

+0

感谢您的信息。将所有数据复制到标准对象的原因是我想模仿应用程序的行为,我试图用Realm替换SQLite。我想在做转换时做最小的改变。我必须根据您的意见重新考虑我的方法。 –