Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most efficient way to store long list of Objects in Realm?

I'm trying to compare Realm with Snappydb (This is my repo for those who would like to have a look at benchmark). I guess my way is wrong, as store-to-db time takes super long time in Realm in compare with Sanppydb.

Benchmark shows following result. As you can see in the image, Realm is around 100-200 times slower than Snappydb. enter image description here

What I'm doing is creating 10,000 objects first and then storing them into the db. So, in my code I store a Booking object in this way (there is a for loop that iterates 10,000 times):

public void storeBooking(final Booking booking) {
        mRealm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                Booking realmBooking = realm.createObject(Booking.class);
                realmBooking.setId(booking.getId());
                realmBooking.setCode(booking.getCode());
                realmBooking.setFareLowerBound(booking.getFareLowerBound());
                realmBooking.setFareUpperBound(booking.getFareUpperBound());
                realmBooking.setPhoneNumber(booking.getPhoneNumber());
                realmBooking.setPickUpTime(booking.getPickUpTime());
                realmBooking.setRequestedTaxiTypeName(booking.getRequestedTaxiTypeName());
                realmBooking.setTaxiTypeId(booking.getTaxiTypeId());
            }
        });
    }

Update

This is Snappydb method for storing Booking object.

public void storeBooking(final String key, final Booking booking) {
        try {
            mSnappyDb.put(key, booking);
        } catch (SnappydbException e) {
            e.printStackTrace();
        }
    }

Update

New results using insertOrUpdate() method and one transaction

enter image description here

like image 333
Hesam Avatar asked Sep 08 '16 03:09

Hesam


1 Answers

Your original solution saves 10000 objects in 10000 transactions and creates 10000 objects for it, so that's pretty much the worst possible approach.


Technically the right way should be this:

public void storeBookings(final List<Booking> bookings) {
    mRealm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            realm.insertOrUpdate(bookings);
        }
    });
}

In most cases when the saved object is not the same as the original object, what I do is this:

public void storeBookings(final List<Booking> bookings) {
    mRealm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            RealmBook realmBook = new RealmBook();
            for(Booking booking : bookings) {
                realmBook = mapper.toRealm(booking, realmBook); // does not create new instance
                realm.insertOrUpdate(realmBook);
            }
        }
    });
}

This solution uses 1 detached object to map the content of the list.

like image 125
EpicPandaForce Avatar answered Oct 06 '22 01:10

EpicPandaForce