Search code examples
objective-cmultithreadinggrand-central-dispatchblockdatabase-performance

Improve The Processing Speed Of Code Objective C


Basically I have a graph view controller (several in fact) in my iPhone Application. The graphs are dependent upon the user selection of different 'scorecards'. The problem however, is that the user may select as many scorecards as they want: They could select hundreds.

In producing the graph, I have many algorithms running and they are quite heavy duty as they reach into core data to extract information, and example of one of my algorithms is below.

-(NSDictionary *) stablefordForEachPersonOnCourse:(NSString *) courseName atDate:(NSString *) date
{

NSDictionary *shotsForEachPersonOnCourse = [[NSDictionary alloc]initWithDictionary:[self shotsForEachPersonOnCourse:courseName atDate:date]];
CoreDataHelper *helper = [[CoreDataHelper alloc]init];
NSMutableDictionary *stablefordWithNames = [[NSMutableDictionary alloc]init];

ScoreCard *card = [helper getScoreCardWithDate:date fromCourse:[helper getGolfCourseWithName: courseName]];

 for (int j = 0 ; j < [[shotsForEachPersonOnCourse allKeys]count]; ++j) {

     Player *player = [helper getPlayerWithName:[[shotsForEachPersonOnCourse allKeys]objectAtIndex:j] fromScoreCard:card];

     NSString *teeColour = player.teePlayed;
     NSArray *arrayOfHolesPlayed = [helper getOrderedArrayOfHolesFromPlayer:player];
     NSArray *arrayOfHoles = [helper getOrderedArrayOfHolesFromTee:[helper getTeeWithColour:teeColour fromCourse:[helper getGolfCourseWithName:courseName]]];
     NSMutableArray *stableFord = [[NSMutableArray alloc]init];

     for (int i = 0; i< [arrayOfHolesPlayed count]; i++) {

         HolePlayed *holePlayed = [arrayOfHolesPlayed objectAtIndex:i];
         Hole *hole = [arrayOfHoles objectAtIndex:i];

         int temp1 = 0, shotsGet = 0;

         int handicap = player.handicap.intValue;
         int strokeIndex = hole.holeSI.intValue;
         int par = hole.holePar.intValue;
         int shotScore = holePlayed.holeScore.intValue;

         if (shotScore >0) {
         while (temp1 >= 0) {

             if(handicap - (strokeIndex + (18*temp1))>= 0)
             {
                 ++shotsGet;
                 ++temp1;
             }
             else temp1 = -1;

         }
         int stableford = (0 - (shotScore - (shotsGet + par))+2);
         if (stableford < 0) {
             stableford = 0;
         }

        [stableFord addObject:[NSNumber numberWithInt:stableford]];
         }
         else if (shotScore <1) [stableFord addObject:[NSNumber numberWithInt:0]];
     }

     [stablefordWithNames setValue:stableFord forKey:[[shotsForEachPersonOnCourse allKeys]objectAtIndex:j]];
     }
return stablefordWithNames;}  

This algorithm calculates the stableford for each person on the particular scorecard. Now when the user selects many scorecards I need a way of rapidly increasing the speed of algorithms such as these.

I have left this question quite open ended - but what is the best way to speed up my code. Obviously, using Grand Central Dispatch (GCD) is a must as this enables the code to run on different cores thus increasing processing power per unit time - but what would be the best way to use GCD on this? Also, should I be turning all my calculations into blocks? Would this make a significant improvement to the speed of calculation?


Solution

  • I have left this question quite open ended - but what is the best way to speed up my code?

    Don't begin by throwing more threads at the problem. You should start by focusing on what is taking the most time:

    • CPU?
    • I/O? (incl. CoreData)
    • Can better algorithms be used?
    • Searching? Sorting?
    • High number of object creation?
    • Can portions of the program be easily expressed using C?

    Then bring those down as much as is reasonable (iterate), then re-evaluate. If you've not optimized your implementation yet, then it is typical to achieve significant gains (e.g. 2x-20x or more) from an initial implementation (while keeping it more maintainable than a concurrent/multithreaded implementation). You may benefit from multithreading, but that should be one of your last resorts, especially if your implementation was not designed for concurrent execution (is not threadsafe).

    Obviously, using Grand Central Dispatch (GCD) is a must…

    Making a correct multithreaded implementation can take a lot of time, and can also consume/introduce a lot of hardware resource demands unnecessarily. Even so, there are alternatives to GCD.

    (If you should perform the work on a secondary thread for UX, that's not just throwing more threads at the problem.)