realm / realm-js

Realm is a mobile database: an alternative to SQLite & key-value stores
https://realm.io
Apache License 2.0
5.62k stars 558 forks source link

Object creating takes very long in ios (react native) #2845

Closed idanCemento closed 3 years ago

idanCemento commented 4 years ago

recently updated from 3.6.4 to 5.0.3. object creating takes much longer that it used to on both simulators and iphones + blocks ui.

Expected Results

quick creating as it used to be

Actual Results

average object creation takes about 400ms and blocks the ui

Code Sample

postRealm.write(() => {
    if (cleanAll) {
        let allPosts = postRealm.objects('post24').filtered('projectId = "' + projectId + '"');
        let allLastUpdateTS = postRealm.objects('lastUpdateTS').filtered('projectId = "' + projectId + '" AND type = "post"');
        postRealm.delete(allLastUpdateTS);
        postRealm.delete(allPosts); 
    }

    preparedPostArray.forEach(post => {
        if (post && post.id) 
            postRealm.create('post24', post, true);
        else {
            console.warn('post missing ID'); 
        }
    });

    if (projectId && ignoreTimestamp)
        postRealm.create('lastUpdateTS', { id: projectId + '_post', lastUpdateTS: newLastUpdateTS, projectId, type: 'post' }, true)
}); 

Versions

eladgel commented 4 years ago

Did the same update and just noticed this too, I've also noticed that when you update an entity you encounter the same issue

bmunkholm commented 4 years ago

Thanks for reporting this @eladgel @idanCemento ! Could any of you possibly provide a self contained sample project that shows this? That would be really helpful so we have something concrete.

idanCemento commented 4 years ago

sorry.. i can't share my project but it used to work very fast before the update

bmunkholm commented 4 years ago

@idanCemento We certainly don't need your full project, but if you could make a small self-contained repro-case which simulates what you do, that would be super helpful. We have no idea what your model looks like and how much data you are adding in those objects.

idanCemento commented 4 years ago

It's complicated. There are thousands of objects, most of them refer to many other models in the system which also has thousands or hundreds of objects. The update is done in one batch but for some reason it takes very long to do every iteration in the transaction. Every thing is indexed

bmunkholm commented 4 years ago

Every thing is indexed That can have an impact on insertion time. How many properties are indexed?

Without an understanding of a synthetic way to reproduce this, it will be hard for us to understand and help.

eladgel commented 4 years ago

@idanCemento Can you try removing the indexed property just for the test? @bmunkholm I have the same issue almost exactly, it happens in an object that holds objects, that some of them have more objects and some have list of objects. I think that my hierarchy goes 4-7 levels deep in total, where every level creates a new object/list of objects

bmunkholm commented 4 years ago

@eladgel Thanks for the feedback! If you have a way to make a minimal repro-case with something similar to what your do - or whatever is needed to show the issue, we would be super grateful! Issues with repro-cases typically get's the highest priority ;-)

Ilann0 commented 4 years ago

+1

tomershohet commented 4 years ago

+1

tomershohet commented 4 years ago

@blagoev We found more info regarding this issue.

On an object that have only native properties it work fine. Then - with each property that being linked to an other property type, it add ~20 milisec to the create action.

  1. That happen only if the property does have a value that need to be set.
  2. Each property adds about 20 milisec, so an object with 10 linked properties, would take about 200 milisec per object. On out case we have around 50K objects, so it would take a couple of hours...
  3. The problem only exist on IOS - on Android it works fine (About 0-1 milisec per linked property)
bmunkholm commented 4 years ago

@tomershohet That's great! Could you possibly cook that down to a minimal repro case that demonstrate this? That would be highly appreciated!

tomershohet commented 4 years ago

@bmunkholm It happen on every create with an object that have any link to another object. Neither of the object don't have anything other then id (And the first one have a link to the second). With every create - it would take about 20 milisec on IOS to add that object.

blagoev commented 4 years ago

@tomershohet Thanks for the information. Could you possibly share a simple schema that we can use to reproduce this.

cheers.

idanCemento commented 4 years ago

schema:

export const parentSchema = {
  name: 'parent',
  schemaVersion: 1,
  properties: {
    id:'string',
    child: 'child'
  }
};

export const childSchema = {
  name: 'child',
  schemaVersion: 1,
  properties: {
    id: 'string'
  }
};

code:

function testRealmObject(realmInstance) {
    let parentRealm = realmInstance.parent;
    parentRealm.write(() => {
        for (let i = 0; i < 55; i++) {
            let obj = {
                id: `parent${i}`,
                child: {
                    id: `child${i}`
                }
            };
            let startTS = new Date();
            parentRealm.create('parent', obj);
            console.log("TCL: testRealmObject -> parentRealm.create ", new Date() - startTS);
        };
    });
}

output:

'TCL: testRealmObject -> parentRealm.create ', 25
'TCL: testRealmObject -> parentRealm.create ', 25
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 24
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 28
'TCL: testRealmObject -> parentRealm.create ', 27
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 24
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 20
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 20
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 24
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 25
'TCL: testRealmObject -> parentRealm.create ', 24
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 24
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 24
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 20
'TCL: testRealmObject -> parentRealm.create ', 20
'TCL: testRealmObject -> parentRealm.create ', 22
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 23
'TCL: testRealmObject -> parentRealm.create ', 24
'TCL: testRealmObject -> parentRealm.create ', 21
'TCL: testRealmObject -> parentRealm.create ', 21

@blagoev @tomershohet

tomershohet commented 4 years ago

Hi, Any updates on the issue? @blagoev

idanCemento commented 3 years ago

hey, I created a sample project that reproduce the issue.

https://github.com/idanCemento/realm-performance

On my IOS simulator, it takes on average 14.41 ms to create an object with reference and 0.03 ms to create a simple object

@bmunkholm @blagoev

idanCemento commented 3 years ago

on my ipad the performance are even worse

realm performance

tomershohet commented 3 years ago

32 millisecond per object. On a usual case where we have about 5K objects, it would take almost 3 minutes...

It wasn't that why on previous versions, i believe it stated acting this way on version 5. Obviously this issue is critical for anyone who uses realm with big data.

Please prioritize this as it is a showstopper.

Thanks

bmunkholm commented 3 years ago

Thanks all - highly appreciate the repo. We will investigate further.

idanCemento commented 3 years ago

hey, any news with this issue? please update if it was or will be investigated.

I'm worried that at this point we should already consider moving our app to use another DB..

please help

bmunkholm commented 3 years ago

We surely will investigate this further. There are some other high priority issues being handled right now, so I don't expect this can be looked at until next week. As a temporary workaround would it be possible for you to downgrade until we have a fix for this?

idanCemento commented 3 years ago

As a temporary workaround would it be possible for you to downgrade until we have a fix for this?

unfortunately no... last versions don't support latest versions of node while react native already requires node@12

blagoev commented 3 years ago

Hi, It is in our high priority list to check. I hope next week we will be able to investigate this.

tomershohet commented 3 years ago

Hi, @blagoev is there any update by any chance? The entire release is waiting for this :-}

jimsideout commented 3 years ago

+1

WJimmyCook commented 3 years ago

I have a single write transaction that creates a bunch of linked objects. Using the latest release it took my app around 110 seconds to complete. I downgraded to version 3.6.5 and the same write transaction took less than 1 second!

One interesting thing to note -- with the latest release if I enable remote debugging then the write transaction is much faster. It's actually even faster than the release build.

bmunkholm commented 3 years ago

@WJimmyCook And this is also just on iOS, and not on Android?

WJimmyCook commented 3 years ago

@bmunkholm Yeah, this is for iOS. I'm not working on an Android version for this app so I'm not sure what Android is like.

steffenagger commented 3 years ago

@bmunkholm I ran @idanCemento's realm-performance on iOS & Android - the bug is iOS specific. See screenshots:

iOSAndroid

mirkodrummer commented 3 years ago

Hi there! I'm having the same issue developing an iPad app. Is there any update on this?

blagoev commented 3 years ago

This is fixed and will be part of our next release. @idanCemento thanks for the top notch report and repro app. cheers

RealmBot commented 3 years ago

➤ Lyubomir Blagoev commented:

fixed in https://github.com/realm/realm-js/pull/3136 ( https://github.com/realm/realm-js/pull/3136 )