Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If-statement vs function pointer

The goal is to change the behaviour in an event loop, depending on whether a checkbox is toggled on or off. The simplest way, that I can think of, is just to test the checkbox state each time the loop is run.

// if-statement

void action() { /* ... */ }


void someLoop() {

  if (checkboxTrue) {
    action();
  }
  // ... other stuff

}

Would the code be more performant and cleaner or in any other way better, if a function pointer was being used? Like this:

// function pointer

void action() { /* ... */ }
void empty() {}
void (*actionPtr)();


void checkboxChanged(int val) {

  if (val == 1)
    actionPtr = &realAction;
  else
    actionPtr = ∅

}

void someLoop() {

  (*actionPtr)();
  // ... other stuff

}
like image 825
Davorin Avatar asked Jan 03 '14 14:01

Davorin


4 Answers

  1. One indirect function call is more expensive than one if condition.

  2. Several if conditions are more expensive than an indirect function call.

  3. Worrying about speed at this point is pointless:
    You are waiting on the latency of the user, and you are handling stuff he can look at (i. e. there won't be huge amounts of checkboxes). Optimizing code that is executed less than a million times per second on a detailed level like this is absolutely pointless.

So, my advise is: stop worrying about the cost of an if or function call while you are programming a user interface. Only think about such stuff inside your time consuming algorithms.

However, if you find that you are indeed using complex if/else ladders and/or switch statements inside your inner loop, you might optimize by replacing those with indirect function calls.


Edit:
You say that you have 600 checks per second. Assuming you have only one if case to handle (the situation where the if is faster), you "save" roughly 6 microseconds per second by not using function pointer indirection, that's 0.0006% of the runtime. Definitely not worth the effort...

like image 137
cmaster - reinstate monica Avatar answered Nov 15 '22 19:11

cmaster - reinstate monica


Not having the conditional branch will obviously save some time, of course it is simply branching around a branch so you are incurring a pipe flush, it is a case of maybe two flushes instead of one (barring processor optimization of course) plus the extra code to do the compare.

extern void fun0 ( unsigned int );
extern void fun1 ( unsigned int );

void (*fun(unsigned int));


void dofun0 ( unsigned int x, unsigned int y )
{
    if(x) fun0(y);
    else  fun1(y);
}

void dofun ( unsigned int y )
{
    fun(y);
}

gives something like this for example

Disassembly of section .text:

00000000 <dofun0>:
   0:   e3500000    cmp r0, #0
   4:   e92d4008    push    {r3, lr}
   8:   e1a00001    mov r0, r1
   c:   1a000002    bne 1c <dofun0+0x1c>
  10:   ebfffffe    bl  0 <fun1>
  14:   e8bd4008    pop {r3, lr}
  18:   e12fff1e    bx  lr
  1c:   ebfffffe    bl  0 <fun0>
  20:   e8bd4008    pop {r3, lr}
  24:   e12fff1e    bx  lr

00000028 <dofun>:
  28:   e92d4008    push    {r3, lr}
  2c:   ebfffffe    bl  0 <fun>
  30:   e8bd4008    pop {r3, lr}
  34:   e12fff1e    bx  lr

You should be able to measure that performance difference if you carefully craft your test. It is going to be a very small difference, but definitely measurable.

like image 31
old_timer Avatar answered Nov 15 '22 20:11

old_timer


Imho, pointers are a bit cleaner for calling routines having many arguments:

int good(int a, int b, int c, char *d) { ... }
int bad (int a, int b, int c, char *d) { ... }
int ugly(int a, int b, int c, char *d) { ... }

Direct calls:

if (is_good) {
   good(1,2,3,"fire!");
} else if (is_bad) {
   bad(1,2,3,"fire!");
} else {
   ugly(1,2,3,"fire!");
}

Indirect calls:

if (is_good) {
   f = good;
} else if (is_bad) {
   f = bad;
} else {
   f = ugly;
}

...

f(1,2,3,"fire!");
like image 33
user2743554 Avatar answered Nov 15 '22 21:11

user2743554


To get exact results, time measurements would be needed, but:
I´m certain that a if has less overhead than a full function call.
->If is faster

like image 39
deviantfan Avatar answered Nov 15 '22 20:11

deviantfan