lundi 4 janvier 2021

Does the compiler optimize away if statements inside loop

I'm going through another programmers code and see the following function (and several variations, are called inside a massive loop and in the critical path) and I'm wondering if the c# compiler is smart enough to optimize it:

public double SomeFunction(double p_lower, double p_upper) {
   double result = 0.0;
   int low = (int)Math.Ceiling(p_lower);
   int high = (int)Math.Ceiling(p_upper);

   for( int i = low; i <= high; ++i){
      double dbl_low;
      double dbl_high;
      
      if (i == low && i == high) {
        dbl_low = low;
        dbl_high = high;
      } else if (i == low) {
        dbl_low = p_lower;
        dbl_high = i;
      } else if (i == high) {
        dbl_low = i - 1;
        dbl_high = p_upper;
      } else {
        dbl_low = i - 1;
        dbl_low = i;
      }
    
      if (dbl_low != dbl_high) {
        result += f(dbl_low,dbl_high);
      }
   }
   return result;
}

What this function does is clear, the range from p_lower to p_upper is split up three parts: Fraction up to the first integer, steps of 1 until the last integer, fraction from last integer to p_upper and call a function on those intervals.

The first condition is the edge case where the total interval is less than 1;

My instinct (from when I learned to program and compilers were horrible) would be to rewrite the code as this:

public double SomeFunction(double p_lower, double p_upper) {
   double result = 0.0;
   double low = Math.Ceiling(p_lower);
   double high = Math.Ceiling(p_upper);
   
   /// edge case
   if ((low - high) < 0.00001) {
     return f(p_lower, p_upper);
   }
   /// first fraction
   result += f(p_lower, low);
   /// whole intervals
   for( double i = low + 1.0; i <= high; ++i){
     result += f(i-1.0, i);
   }
   /// add last fraction and return
   return result + f(high - 1.0, p_upper);
}

This way, there is not a whole cascade of conditional statements that is evaluated every loop, the first of which will always be false after the first, the second will always be true except for the final one. In fact there is no conditional in the loop, since the last condition has been incorporated in the loop range.

The loop counter is a double which should not be an issue since the range for low and high is 0.0 ... 120.0 all of which are exact as a double.

Am I wasting my time and does the compiler handle all this and is all I gain some readability?

Aucun commentaire:

Enregistrer un commentaire