# Thread: Determining operator at run time efficiently (without "if')

1. ## Determining operator at run time efficiently (without "if')

I have the stretch of pseudocode below. We have a very long running loop and the code needs to be highly efficient. We need to run the function using either "<" or ">" depending upon circumstances at runtime when is called.
The first construct with two separate functions works fine. Except it is very verbose having to clone a lot of code for each function.
The 2nd construct combines both functions and determines the < or > at runtime based upon a parameter. This works but is very slow due to the "if" statement.
I thought C++ may solve this with a lambda function as shown. But apparently this is recalling the function each time and this is equally slow.
Is there some "nice" way to combine my functions and efficiently determine the "< ,>" parameter at runtime?

Thanks
Fritz
Code:
```PSUEDOCODE
//Assume loop is very long. Efficiency is important here.
(1) coding two separate functions for GT and LT: efficient but lengthy with redundant code
funct1()
{
loop:
[lots of code]
if (a < b) blah-blah
[lots more code]
}

funct2()
{
loop:
[lots of code]
if (a > b) blah-blah
[lots more code]
}

//(2) consolidate into one function. works but "if" statement takes too much time for large loop.
funct(char optype)
{
loop:
[lots of code]
if(optype == 'L' (a < b) {blah-blah}
else (a > b) {blah-blah}
[lots more code]
}

//(3) attempt to use lambda function. runs slow-probably lamda is execute over and over

funct(char optype)
auto greater = [&](auto a, auto b) -> bool
{
if(optype == 'L')  return a < b;
else return a > b;
};

loop:
[lots of code]
if (greater(a, b)) {blah-blah}
else (a > b) {blah-blah}
[lots more code]
}``` 2. I don't fully understand, but perhaps you could just swap(a, b) before the loop under some condition. Does that make sense? 3. Originally Posted by sonnichs
I thought C++ may solve this with a lambda function as shown. But apparently this is recalling the function each time and this is equally slow.
What probably happened is that the lambda function was inlined, so the end result was the same.

john.c's swapping idea might work, but if you're doing something a bit more complex, another possibility to try might be:
Code:
```functBlahBlahL()
{
if (a < b) blah-blah
}

functBlahBlahG()
{
if (a > b) blah-blah
}

template<functBlahBlah>
funct()
{
loop:
[lots of code]
functBlahBlah()
[lots more code]
}

funct<functBlahBlahL>()```
So my idea is that the blah-blah code to execute depending on the comparison is placed into functions, then you turn the original function into a function template and pass these functions as template arguments depending on whether you want GT or LT. If the blah-blah code is inlined in both cases (I'm assuming they're different hence the swap idea wouldn't work), then you basically end up with your original two big functions, but now as a single function template. 4. I fail to see how a single "if" can have a performance impact compared to "lots of code".

Is this backed up by some actual profiling data, or just finger in the air guessing.

> Assume loop is very long. Efficiency is important here.
Maybe that's the problem.
Compilers can struggle with very large bloatware. 5. Yeah, now that I read this again, it doesn't make sense. Maybe you implemented it wrong and that somehow led to a longer runtime. For instance, it seems that your code (2) above should be more like this:
Code:
```funct(char optype)
{
loop:
[lots of code]
if (optype == 'L')
{
if (a < b) {blah-blah}
}
else
{
if (a > b) {blah-blah}
}
[lots more code]
}``` 6. For instance, if you mistakenly implemented it like:
Code:
```  if (optype == 'L' && a < b) {blah-blah}
else if (a > b)             {blah-blah}```
Then if optype == 'L' is true and a < b is false, the > test will also be tested (and probably be true) , which is not what you want. That would increase the runtime. 7. Another possible mistaken implementation is leaving out the braces to delimit the outer "if" block like this:
Code:
```   if (optype == 'L')
if (a < b) {blah-blah}
else
if (a > b) {blah-blah}```
The above actually means this:
Code:
```   if (optype == 'L')
if (a < b)
{blah-blah}
else if (a > b)
{blah-blah}```
which is again not what you want and would cause a call of the function with optype == 'L' to take a longer time than the original code while a call with optype != 'L' would take a shorter time. 8. Sorry for the delay here-I spent most of yesterday dealing with an errant 3D printer. At any rate I was trying save you having you look at my code using pseudo code but it lead to confusion and I apologize. I am attaching one example of the actual code here (there are several similar ones in about 10,000 lines). This type of pattern-copying the same code for both the GT and LT condition-- occurs a lot and I want to condense the code for simplicity. (if you search on the "<" sign you will find the statement in question)
Keep in mind that the user calls the appropriate routine dynamically so it cannot be "hard compiled" with a #define for example.
I have tested the code with timers and the addition of an "if" statement takes up to 20% extra time depending matrix size and upon which compiler I use ranging from the gnu with O1 and O3 to the MPLAB. More important however is that this raises a general question regarding the ability of C++ to have a function that shares all code except perhaps one line. It does this type of thing with Class overloading but not, to my knowledge, for functions.
My 3rd example in the attachment shows my attempt to use the "lambda" but I cannot really find documentation to clarify this method and perhaps it is not even the right way to go.

cheers
Fritz

Code:
```  //======================================== colsort_bubble =================================
IRIS_EU_STATUS Matrix::colsort_bubble()
{
uint32_t ii, jj, kk;
Data_t holdsw;
bool swapped;

for (jj = 0; jj < ncols; jj++)
{
for (ii = 0; ii < mrows - 1; ii++)
{
swapped = false;
for (kk = 0; kk < mrows-ii-1; kk++)
{
if (pDataBuffer[kk*ncols + jj] > pDataBuffer[kk*ncols + jj + ncols] )
{
holdsw = pDataBuffer[kk*ncols + jj]; //swap elements
pDataBuffer[kk*ncols + jj] = pDataBuffer[kk*ncols + jj + ncols ];
pDataBuffer[kk*ncols + jj + ncols ] = holdsw;
swapped = true;
} //end if
} //end for(kk)
if (swapped == false) break;
} //end for(ii)
} //end for(jj)

return(0);
} //end colsort_bubble

//======================================== colsort_bubble descending ======================
IRIS_EU_STATUS Matrix::colsort_bubble_desc()
{
//This function reverse sorts the matrix on a column by column basis. Specifying Matrix X(N,1) will
//allow use as a col vector sort.
uint32_t ii, jj, kk;
Data_t holdsw;
bool swapped;

for (jj = 0; jj < ncols; jj++)
{
for (ii = 0; ii < mrows - 1; ii++)
{
swapped = false;
for (kk = 0; kk < mrows-ii-1; kk++)
{
if (pDataBuffer[kk*ncols + jj] < pDataBuffer[kk*ncols + jj + ncols] )
{
holdsw = pDataBuffer[kk*ncols + jj]; //swap elements
pDataBuffer[kk*ncols + jj] = pDataBuffer[kk*ncols + jj + ncols ];
pDataBuffer[kk*ncols + jj + ncols ] = holdsw;
swapped = true;
} //end if
} //end for(kk)
if (swapped == false) break;
} //end for(ii)
} //end for(jj)

return(0);
} //end colsort_bubble

//======================================== colsort_bubble both ways ========================
IRIS_EU_STATUS Matrix::colsort_bubble_both(char dir)
{
uint32_t ii, jj, kk;
Data_t holdsw;
bool swapped;

auto greater = [&](auto a, auto b) -> bool
{
if(dir == 'd')  return a < b;
else return a > b;
};

for (jj = 0; jj < ncols; jj++)
{
for (ii = 0; ii < mrows - 1; ii++)
{
swapped = false;
for (kk = 0; kk < mrows-ii-1; kk++)
{
//if (pDataBuffer[kk*ncols + jj] > pDataBuffer[kk*ncols + jj + ncols] )
if (    greater(   pDataBuffer[kk*ncols + jj] , pDataBuffer[kk*ncols + jj + ncols]   )     )
{
holdsw = pDataBuffer[kk*ncols + jj]; //swap elements
pDataBuffer[kk*ncols + jj] = pDataBuffer[kk*ncols + jj + ncols ];
pDataBuffer[kk*ncols + jj + ncols ] = holdsw;
swapped = true;
} //end if
} //end for(kk)
if (swapped == false) break;
} //end for(ii)
} //end for(jj)

return(0);
} //end colsort_bubble```  Popular pages Recent additions blah-blah, code], function, loop, [lots 