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.
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.
Comments