title: performance optimizing critical code in iOS app
body: <p>I am trying to optimize the performance of a critical part of my app. Written in C, the code loops through all pixels of sourceImage and calculates the "color distance" to each of its neighbors, deciding if to record a value derived from colorDistance, before moving on to the next neighbor.</p>
  
  <p>Instrumenting the app in XCode revealed that 70% of the time was spent on what appears to be a simple float calculation—seven times longer than a code line that has three powf and one sqrtf (the calculation of colorDistance consuming 10.8%). </p>
  
  <p>On the left of some code lines below you will see the percentage time spent as it was copied from XCode Instruments. (I also noticed other mundane code lines that surprisingly had a relatively high percentage, even though not close to those I've mentioned above).</p>
  
  <p>Any tips on where and how to optimize would be greatly appreciated.</p>
  
  <p>cheers</p>
  
  <pre><code>     for (int row = 1; row &lt; height - 1; row++)
          {            
              for (int col = 1; col &lt; width - 1; col++)
              {
                  int pixelIndex = (col + row * width);
  1.7%            int pixelIndexIntoImage = pixelIndex * COMPONENTS_PER_PIXEL;
  
                  // loop over pixel's 8 neighbours clockwise starting from neighbor id 0
                  // using Nx[] and Ny[] as guides to calculate neighbour locations
  1.6%            for (int n = 0; n &lt; 8; n++)
                  {
  5.3%                int neighborIndex = pixelIndex + Nx[n] + width * Ny[n];
                      int neighborIndexIntoImage = neighborIndex * COMPONENTS_PER_PIXEL;
  
  
                      // skip neighbors that are not a foreground or background
  3.3%                uint8_t labelValue = labelsMap[neighborIndex];
  1.1%                if (labelValue == LABEL_UNKNOWN_VALUE)
                          continue; 
  
  
  
                      // "color distance" between the pixel and the current neighbour
                      float colorDistance;
  
  1.4%                if(numColorComponents == 3)
                      {
  5.3%                    uint8_t redPixel = sourceImage[pixelIndexIntoImage  ];
                          uint8_t grnPixel = sourceImage[pixelIndexIntoImage+1];
                          uint8_t bluPixel = sourceImage[pixelIndexIntoImage+2];
  
                          uint8_t redNeigh = sourceImage[neighborIndexIntoImage  ];
                          uint8_t grnNeigh = sourceImage[neighborIndexIntoImage+1];
                          uint8_t bluNeigh = sourceImage[neighborIndexIntoImage+2];
  
  10.8%                   colorDistance = sqrtf( powf(redPixel-redNeigh, 2) + 
                                                 powf(grnPixel-grnNeigh, 2) + 
                                                 powf(bluPixel-bluNeigh, 2));
                      }
                      else
                      {
                          uint8_t pixel = sourceImage[pixelIndexIntoImage   ];
                          uint8_t neigh = sourceImage[neighborIndexIntoImage];
  
                          colorDistance = fabsf(pixel - neigh); 
                      }
  
  71.2%               float attackForce = 1.0 - (colorDistance / MAX_COLOR_DISTANCE);
  
                      if (attackForce * strengthMap[neighborIndex] &gt; revisedStrengthMap[pixelIndex])
                      {
                          //attack succeeds
  
                          strengthMap[pixelIndex] = attackForce * revisedStrengthMap[neighborIndex];
  
                          outputMask[pixelIndex] = labelsMap[neighborIndex];
  
                          isConverged = false; // keep iterating
  
                      }
                  }
  
              }
  
          }
  </code></pre>
  
  <p>Definition of variables</p>
  
  <pre><code>uint8_t *sourceImage; // 4 bytes per pixel
  uint8_t *labelsMap, *outputMask; // 1 byte per pixel
  int     numPixels = width * height;
  float   *strengthMap        = (float*) malloc(sizeof(float)*numPixels);
  float   *revisedStrengthMap = (float*) malloc(sizeof(float)*numPixels);
  short   Nx[] = {-1,  0,  1, 1, 1, 0, -1, -1}; 
  short   Ny[] = {-1, -1, -1, 0, 1, 1,  1,  0}; 
  </code></pre>
  
  <p>Following advise I received (multiplication is "cheaper" than division), I revised one code line, and interestingly enough, 71.2% dropped to 1.7%, BUT the "if" statement just below shot up to 64.8% — i just don't get it!</p>
  
  <pre><code>1.7%               float attackForce = 1.0 - (colorDistance * MAX_COLOR_DISTANCE_INV);
  
  64.8%              if (attackForce * strengthMap[neighborIndex] &gt; revisedStrengthMap[pixelIndex])
  </code></pre>