Solved

Performance (and readability)

Posted on 2004-03-23
10
205 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
ID: 10661737
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
ID: 10661756
should say:
if (fvail >=val[1][i] && score >=val[2][i])

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

Expert Comment

by:burtdav
ID: 10663354
/* 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 11

Expert Comment

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

Expert Comment

by:burtdav
ID: 10663804
If I wasn't certain I was right, I'd say so.
But, no shame on you for a simple slip-up, griessh.
:)
0
 
LVL 3

Expert Comment

by:guynumber5764
ID: 10663882
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
ID: 10663914
/* 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
ID: 10667535
GlennJ,

Could you please post the entire if elseif conditionals..

b.
0
 
LVL 4

Expert Comment

by:booki
ID: 10667913
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
ID: 10667961
Or you could binary search
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
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.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

749 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