Search code examples
ioscocoafor-loopcore-plotnsoperationqueue

Using NSOperatonQueue to speed up long calculation


I'm looking for ways to speed up a lengthy calculation (with two nested for-loops), the results of which will be shown in a plot. I tried NSOperationQueue thinking that each of the inner for loops would run concurrently. But apparently that's not the case, at least in my implementation. If I remove the NSOperationQueue calls, I get my results in my plot, so I know the calculation is done properly.

Here's a code snippet:

    NSInteger half_window, len;

    len = [myArray length];

    if (!len)
        return;

    NSOperationQueue    *queue = [[NSOperationQueue alloc] init];

    half_window = 0.5 * (self.slidingWindowSize - 1);
    numberOfPoints = len - 2 * half_window;

    double __block minY = 0;
    double __block maxY = 0;
    double __block sum, y;

    xPoints = (double *) malloc (numberOfPoints * sizeof(double));
    yPoints = (double *) malloc (numberOfPoints * sizeof(double));

    for ( NSUInteger i = half_window; i < (len - half_window); i++ )
    {
        [queue addOperationWithBlock: ^{

        sum = 0.0;

        for ( NSInteger j = -half_window; j <= half_window; j++ )
        {
            MyObject *mo = [myArray objectAtIndex: (i+j)];
            sum += mo.floatValue;
        }

        xPoints[i - half_window] = (double) i+1;

        y = (double) (sum / self.slidingWindowSize);
        yPoints[i - half_window] = y;

        if (y > maxY)
            maxY = y;

        if (y < minY)
            minY = y;
        }];

        [queue waitUntilAllOperationsAreFinished];
    }

    // update my core-plot
    self.maximumValueForXAxis = len;
    self.minimumValueForYAxis = floor(minY);
    self.maximumValueForYAxis = ceil(maxY);

    [self setUpPlotSpaceAndAxes];
    [graph reloadData];

    // cleanup
    free(xPoints);
    free(yPoints);

Is there a way to make this execute any faster?


Solution

  • You are waiting for all operations in the queue to finish after adding each item.

    [queue waitUntilAllOperationsAreFinished];
    }
    
    // update my core-plot
    self.maximumValueForXAxis = len;
    

    should be

    }
    [queue waitUntilAllOperationsAreFinished];
    
    
    // update my core-plot
    self.maximumValueForXAxis = len;
    

    You are also setting sum variable to 0.0 in each operation queue block.