Solved

Performance (and readability)

Posted on 2004-03-23
10
203 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
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
List out all word 7 289
Acrinis True image 2 77
SBS server C drive at zero no matter what I delete . Where is the disk space going ?? 9 80
delete-remove 14 84
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

786 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