J. Doe
J. Doe

Reputation: 43

Realm limit query results

I'm new to Realm, and I've already seen this answer about limiting realm queries (in a lot of other places too).

My problem is that the following code is taking too long to load the data into the array when the amount of data gets big:

RLMResults* rlm = [[Item class] objectsWithPredicate:predicate]; // this loads fast
NSArray* results = [rlm valueForKey:@"self"]; // this is slow

as far as I know I can't limit the results using the predicate too, so I am trying to limit the results like this example in the realm website, as follows:

RLMResults* rlm = [[Item class] objectsWithPredicate:predicate]; // this loads fast
NSMutableArray* results = [@[] mutableCopy];

for (NSInteger i = 0; i < 5; i++) {
    Item* item = rlm[i]; // only the first call (when i == 0) is slow here
    [results addObject:item];
}

so the interesting thing here is that only the first call of rlm[i] (rlm[0]) is taking long, and afterwards (when i > 0) the call works fast.

Am I doing something wrong? or is there any way to load big amount of data faster or to limit the results?

Thank's a lot!

Upvotes: 4

Views: 3867

Answers (1)

TiM
TiM

Reputation: 15991

Just like it says in the Realm documentation, the contents of RLMResults are lazy-loaded. It's built to try and defer 'pre-loading' anything until it is absolutely necessary. When you loop through each object it and add it to an NSArray, that's forcing each object to get lazily-loaded, which will (understandably) result in a performance hit. It's also probably that the bulk of the predicate query is being executed lazily as well, which is why you get the performance hit when you access the first object in the results set, and not when you're creating the RLMResults object.

If you consider this performance hit from doing this is unacceptable, you might want to consider trying a different approach to this. For example, instead of copying the objects to an NSArray, use the RLMResults object, and keep track of only the objects you want using an NSRange object. Additionally, since only the initial load is slow, I would also suggest you try and optimise your predicate query as well, for example, making sure each property you're searching against has been marked as indexed.

If worse comes to worse, sometimes long performance hits can't be helped, and if that's the case, you can mitigate any UI freezing by offloading it to a background thread.

I hope that helped!

Upvotes: 3

Related Questions