Solved

Performance (and readability)

Posted on 2004-03-23
10
201 Views
Last Modified: 2010-04-15
I have a large number of test condition that I need to evaluate based upon 2 values (one is a double, the other is an int).  For example, here is what I have now...

if ( strcmp(myString, "CONDX") == 0 )
     if (( fVal >=3.0 && score >= 344 ) ||
         ( fVal >= 4.5 && score >= 294) ||
         ( fVal >=6.0 && score >= 240 ) ||
         // 20 more conditionals go here... )
     {
     }
else if ( strcmp(myString, "LIMTD") = 0 )
     if (( fVal >=3.0 && score >= 487 ) ||
         ( fVal >= 4.5 && score >= 428) ||
         ( fVal >=6.0 && score >= 294 ) ||
         // 20 more conditionals go here... )
     {
     }

There is no formula that can be applied between fVal and score.
The breaks for fVal are ALWAYS the same (3, 4.5, 6, etc - for all 23 comparisons).

Is there  a more elegant way to write this?  Is the performance of this approach fairly fast (this comparison is done ALOT).
0
Comment
Question by:GlennJ
  • 3
  • 3
  • 2
  • +2
10 Comments
 
LVL 11

Accepted Solution

by:
griessh earned 125 total points
Comment Utility
Hi GlennJ,

Depending on the implementation of your compiler and the right optimization settings you should be OK. A 'good' compiler will stop evaluating the conditions once it found a TRUE in the list.
For readability ... Instead of hardcoding these values in if statements I would create arrays with pairs of fVal and score and just loop through the array elements (that would also ensure that you only run as many tests as needed)
if (strcmp(myString, cond) == 0 )
{
  i=0
  while (i<endLoop)
     if (fvail >=val[1][i] && score >=ascore[2][i])
     {
         // do something
         i=endLoop;
     }
     endLoop++;
  }

======
Werner
0
 
LVL 11

Expert Comment

by:griessh
Comment Utility
should say:
if (fvail >=val[1][i] && score >=val[2][i])

... but that's just an idea.
0
 
LVL 5

Expert Comment

by:burtdav
Comment Utility
/* You'll get best performance out of the hard-code you have (it's part of the C standard, not compiler-specific, to do short-circuit evaluation); you'll get best performance if you evaluate the most commonly true conditions first.

gnessh's idea of storing your condition values in arrays is a good one, though, as long as performance here is not too critical (I don't imagine it would be a bottleneck) - it will improve legibility.
*/

const int MAX_STR_IDX = 2;
const int MAX_BOUND_IDX = 23;
char *str[MAX_STR_IDX] = [
   "CONDX",
   "LIMTD"
];
double fValBound[MAX_FVAL_IDX] = [3.0, 4.5, 6.0, ...];
int scoreBound[MAX_STR_IDX][MAX_FVAL_IDX] = [
   [344, 294, 240, ...],
   [487, 428, 294, ...]
];

/* you can improve performance a little by sorting both sets of parallel arrays above by likelihood of each case
*/

int i, j, conditionMet;
for (i = 0; i < MAX_STR_IDX && strcmp(myString, str[i]); i++);
if (!strcmp(myString, str[i])) {
   for (j = 0, conditionMet = 0; j < MAX_BOUND_IDX && conditionMet == 0; j++) {
      if (fVal >= fValBound[i][j] && score >= scoreBound[i][j]) {
         conditionMet = 1;
      }
   }
   if (conditionMet) {
      /* here is where your conditional code goes */
      /* note that the variable i contains the index of the string that myString matched, if you need that. */
   }
}
0
 
LVL 11

Expert Comment

by:griessh
Comment Utility
... shame on me ... you are right about the short-circuit evaluation
0
 
LVL 5

Expert Comment

by:burtdav
Comment Utility
If I wasn't certain I was right, I'd say so.
But, no shame on you for a simple slip-up, griessh.
:)
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 3

Expert Comment

by:guynumber5764
Comment Utility
It looks like there might be also be a performance gain by preconverting fVal to an int before evaluation so that you can make all your comparisons int-to-int.  The benefit gained (if any) will ultimately depend on how deep into the conditional you go each time.

int iVal = 10 * fVal;
if ( strcmp(myString, "CONDX") == 0 )
     if ((iVal >=30 && score >= 344 ) ||
         ( iVal >= 45 && score >= 294) ||
         ( iVal >=60 && score >= 240 ) ||
         // 20 more conditionals go here... )
     {
    etc.

If you want more speed, arrange your conditional so the most common cases are first.  If you want more maintainability, use the arrays suggested above and leave the conditionals in natural order.
0
 
LVL 5

Expert Comment

by:burtdav
Comment Utility
/* For speed and maintainability, with a bit of extra effort, you could sort the arrays at run-time (once, just after they're initialised), based on another parallel array which would contain the order (say, little numbers for common cases and big ones for rare cases) like so:
*/

int priority[MAX_BOUND_IDX] = [3, 1, 2, ...];
0
 
LVL 4

Expert Comment

by:booki
Comment Utility
GlennJ,

Could you please post the entire if elseif conditionals..

b.
0
 
LVL 4

Expert Comment

by:booki
Comment Utility
GlennJ,

Sorry, you can ignore my last post..  the only way I can think of to make the test faster is to use a lookup table.  Granted this is probably overkill as the gains will likely total an insignificant percantage of the runtime and such a table would require a significant chunk of memory.

b.
0
 
LVL 84

Expert Comment

by:ozo
Comment Utility
Or you could binary search
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now