简体   繁体   中英

Can this loop be optimized?

I'm at the debugging/optimization phase with an iPhone app. I have one bottleneck left - the only place where the program has a noticeable lag, and it's in the following loop: (By the way, I've renamed the vars with letters and types. (The real names are much more human-readable in the actual app, but make little sense out of context, so I hope this is clear enough.) Here's the loop:

for(i=0;i<xLong; i+=yFloat*zShort){
  aFloat=0.0;
  for(int j=i;j<i+yFloat*zShort;j++){
    aFloat=hArray[j]/kFloat;
  }
  bNSNumber = [NSNumber numberWithFloat:aFloat]; 
  [cNSMutableArray addObject:bNSNumber];
}

All objection creation and clean-up is outside of this loop.

(It should be pretty straight forward what's happening here, but basically I have a very large array (in the millions) and I'm going through that array at chunks of yFloat*zShort length, adding all of the elements in that chunk, and inserting that final sum in another array. So if hArray is a million elements long, and my chunk length is 200, I'll sum the first 200 elements, insert that total in cNSMutableArray, and move on to the next 200 elements in hArray. In the end, cNSMutableArray will be 5000 elements long.)

When the outer loop is around 25k and the inner loop is around 200, this code takes about 4 seconds to run. I would sure like to get that down as much as possible, as in the real world, the outer loop might be quite a bit larger.

Any ideas how to quicken this up?

Thanks for any ideas you have!

Have you tried to make a C style float array instead of using a NSMutableArray? the overhead of creating that many wrappers (NSNumber) can add up.

First off, from your description it sounds like the inner loop should read:

for(int j=i;j<i+yFloat*zShort;j++){
    aFloat+=hArray[j]/kFloat;
}

Anyway, since kFloat is not changing, you can move that out of the loop and do the division once:

for(int j=i;j<i+yFloat*zShort;j++){
    aFloat+=hArray[j];
}
aFloat/=kFloat;

That said, this can affect the accuracy of the final value. Without knowing exactly what you are doing, I don't know if that will matter.

I see that you already got a nice speedup, but here's my two cents: Floating-point division is notoriously expensive; you could precompute

float invKFloat = 1.0f / kFloat;

and then mulitply by this instead of dividing by kFloat. This means you only have to do the division once, instead of every time in the outer loop.

This seems like the kind of calculation that should be spun off in a background thread.

You have several options- NSOperation is a viable alternative, but depending on your data structures it might be easier to use detachNewThreadSelector:toTarget:withObject:

You really want to avoid creating objects inside a tight loop. Every time you do that, you're allocating a new object on the heap, which involves a hash insert.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM