android - Realm 比 SQLite 花费更多时间进行读写

标签 android sqlite realm

我正在尝试在 Android 应用程序中用 Realm 替换 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 .写入时间几乎与我的实际应用程序相似。对于 Realm ,示例中的读取时间有所改善。

我在示例中为所有属性使用单一数据类型字符串,因为它在实际应用程序中很好地混合了数据类型。

最佳答案

您在此处编写的测试看起来是正确的,因此您获得的数字对于运行它的硬件来说可能相当准确。但请注意,众所周知,基准测试很难做到正确,并且会受到许多您无法控制的因素的影响(例如,其他正在运行的应用程序/传感器/GC)。

下面是一些让您的 Realm 代码更简单的建议,但请注意,这不会改善您的基准测试结果,只会让您的代码更易于阅读和维护:

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) 删除特定类型的所有项目更快。

关于android - Realm 比 SQLite 花费更多时间进行读写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35765431/

相关文章:

ios - 执行从一个列表到另一个更新属性值的 Realm 迁移

swift - RealmSwift,它不起作用

android - 膨胀类 android.support.design.widget.FloatingActionButton 时出错

android - 我如何在android中获取图像矩阵坐标?

android - toast "sending message to a Handler on a dead thread"

java - 严重 : null java. sql.SQLException

android - 计算两个日期之间耗时,在不同的设备上给出不同的结果

android - 在不丢失 Android 数据的情况下更新数据库表

android - Android Marshmallow libsqlite.so 源码调用ftruncate时如何使用ftruncate64?

java - 为什么我在使用realm.executeTransactionAsync()方法时遇到编译时错误?