Unable to improve speed of operation of ios app using grand central dispatch

Kunal Shrivastava

The time consuming task at hand is to query a database to get latitude and longitude values of some paths and trails. Now, I have several of these database operations to be performed for different types of trails and path. I am using the following to:

dispatch_async(myBackgroundQueue, ^(void) {

            // do some time consuming things here
            [self queryForHiking: ulLat ulLong:ulLon lrLat:lrLat lrLong:lrLon];

            dispatch_async(dispatch_get_main_queue(), ^{

                // do some things here in the main queue
                // for example: update UI controls, etc.
                [self drawOnMap];
            });
        });

Like the above block of code, I have 5 blocks like this. The drawOnMap function draws the trails and path formed on the map. But it is taking a lot of time to render all the paths(from different queries) on the map. Especially, on a higher zoom level, where there is more data to be rendered, the app gets hanged and takes a lot of time to resume and display the data. How can I make it efficient?

EDIT: I think the query takes a lot of time here and I have 5 of such queries which are independent from one another. The following is one of my five query function:

 - (void)queryForHikingTrails:(NSString*)ulLat ulLong:(NSString*)ulLong lrLat:(NSString*)lrLat lrLong:(NSString*)lrLong
 {
     @try {
         [_db inDatabase:^(FMDatabase *db) {

             FMResultSet *trails = [db executeQueryWithFormat:@"SELECT ID2,Latitude, Longitude FROM hikingtrails WHERE Latitude BETWEEN %@ and %@ AND Longitude BETWEEN %@ and %@", lrLat, ulLat, lrLong, ulLong];

             hikingTrails = [self buildTrails:trails];
         }];
     }
     @catch (NSException *e) {
         NSLog(@"Error Querying for Trails: %@ - %@", [e name], [e reason]);
     }
     @finally {
     }
 }

The following is the time taken when I run just this query(hiking):

Time taken by the query: 0.053462 Time taken by the redraw function (drawOnMap)=0.000008

When I run two queries(hiking+some other trails):

Time taken by the query: 2.681138 Time taken by the redraw function (drawOnMap)=0.000010

I don't have the privilege to change the database in any way. i.e., I cannot split the table or normalize it.

The database consist of around 18000 entries for hiking alone which the above function is trying to query.

Is there any way besides applying the database optimization to make the queries fast, at least run them in the background simultaneously (all 5)?

EDIT: I have further investigated and found that it is only one query that is taking a lot of time(11.7834) while others are not taking much time. How should I handle this particular query? Is there a way by which I can make this query run in the background without blocking the mapview. I don't know how that will be possible because each time this query is run the mapview is refreshed by the function drawOnMap. Please guide me.

erikprice

I'm not sure if the approach I suggest below works for you, but maybe it can be of some help. It uses an operation queue to execute your queries concurrently, and only when they are all finished does it call -[self drawOnMap]. However, in order for it to work correctly, each of your queries has to block the current thread. I inferred from your original GCD-based code that this was the case. But it also assumes that your query methods can execute concurrently in safety (e.g., that whatever you do with the query results can be done safely from multiple threads).

NSOperation dependencies give you an easy way to specify that work may be performed concurrently, and then do one final update when that work is complete:

self.queryQueue = [[NSOperationQueue alloc] init];

NSBlockOperation *queriesOperation = [NSBlockOperation blockOperationWithBlock:^{
    [self queryForHiking:ulLat ulLong:ulLon lrLat:lrLat lrLong:lrLon];
}];
[queriesOperation addOperation:^{
    [self performSomeOtherQuery];
}];
[queriesOperation addOperation:^{
    [self performYetAnotherQuery];
}];
// do this for each of your queries

NSOperation *drawOperation = [NSBlockOperation blockOperationWithBlock:^{
    [self drawOnMap];
}];
[drawOperation addDependency:queriesOperation];

[self.queryQueue addOperation:queriesOperation];
[NSOperationQueue.mainQueue addOperation:drawOperation];

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

NSOperation vs Grand Central Dispatch

iPhone - Grand Central Dispatch main thread

Grand Central Dispatch (GCD) vs. performSelector - need a better explanation

using dispatch_sync in Grand Central Dispatch

Core Data and threads / Grand Central Dispatch

Workaround on the threads limit in Grand Central Dispatch?

Grand Central Dispatch async vs sync

dispatch_async vs. dispatch_sync using Serial Queues in Grand Central Dispatch

Figuring out syntax for Grand Central Dispatch in Swift

Using Grand Central Dispatch in Swift to parallelize and speed up “for" loops?

Grand Central Dispatch (GCD) in swift

Grand Central Dispatch: What happens when queues get overloaded?

My Grand Central Dispatch usage: Am I using it correctly?

Why will the following simple grand central dispatch program not work correctly?

How to draw to GLKit's OpenGL ES context asynchronously from a Grand Central Dispatch Queue on iOS

Timer with Grand Central Dispatch

Using sqlite on iOS with grand central dispatch

What is the NSOperations' advantage compared wih Grand Central Dispatch(GCD)?

Transforming a code to Grand Central Dispatch

Loading sprites in cocos2d using grand central dispatch

Understanding the Grand Central Dispatch

How to use "loop" parallel processing by using GCD (grand central Dispatch )

Trouble with Grand Central Dispatch using Swift

problems using Grand Central Dispatch IOS Swift Xcode 6.3.1

Grand Central Dispatch alternative to using an NSTimer - invalidating multiple times

Where is libdispatch AKA Grand Central Dispatch imported?

Is it good practice to send a delayed semaphore_signal to a semaphore in a macOS Grand Central Dispatch App?

Grand Central Dispatch

Completion handler in serial Grand Central Dispatch