2
\$\begingroup\$

In my program(C++), I'm going to use callback functions to process input from the keyboard and mouse and constantly draw a scene. How these functions process information will change depending on the state of the program; like I would have certain functionality assigned to several keys, say the arrow keys move the highlighter in the main screen, but I want their functionality to change in another screen. I'm using OpenGL with GLUT, and it's possible to change the keyboard function for example by assigning a different function pointer to it.

The method I used in the past was to define multiple processing functions, each one for a specific task. For example, I have a keyboard for the main menu, but when a different screen is viewed, the function is changed by assigning the appropriate function pointer:

glutKeyboardFunction(MainMenueKeyboardFuncPtr);

But now, I'm wondering if using conditional statements within one function is a better approach.

My question is: are there any performance issues with the conditional functions approach? I'm thinking to define a single function, say for the keyboard, to process keyboard input in all situations:

void KeyInputProcess(int key)
{
   select(SCREEN)
 {

   case MAIN_SCREEN:

  select(key)
   {
 /*process input*/
   }
   break;

    case OPTIONS_SCREEN:

     select(key)
     {
      /*process differently from MAIN_SCREEN*/
     }
     break;
 }



}

Would the checking that takes place every time the function is called have a significant impact on the performance? Which approach is better if I want to maximize performance?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ It's C++. I changed the tag and I'll add it in the body of the question. \$\endgroup\$
    – Hex4869
    Jan 29 '14 at 13:21
2
\$\begingroup\$

My question is: are there any performance issues with the conditional functions approach?

In a word: no.

The additional performance cost is an extra select statement, whose cost probably depends on the number of switch options in the select.

I say "no" because I expect that the performance cost for a few extra instructions is measured in nanoseconds: and there aren't enough keystrokes per second for that to make a difference. Also the actual work you do (i.e. calling OpenGL functions) is probably/hopefully more significant than the performance of the code required to get there; it's like, "Q: Is calling a subroutine expensive? A: Probably not as expensive as executing/running the subroutine."

The befit of using "function pointers" (or perhaps a different subclass for each screen) is more to do with the code's maintainability and readability: for example, it would let you have different people creating each screen; to be contrasted with having a single KeyInputProcess function, where all handling for every screen is defined in the same function.

Taking the trouble to create an abstract base class for a screen (with concrete subclasses for specific screens, and a virtual KeyInputProcess method) may make more code more maintainable (easier to add new functionality without changing existing functionality, nor requiring previously-simple methods to become too complicated) On the other hand, for a smaller project with one programmer, defining many abstract and concrete classes might be 'over-engineering' (the Wikipedia article for over-engineering says, "See also: YAGNI"). Beware that if you practice YAGNI then, later when you do need it, you ought to be good at refactoring: i.e. adding structure later to previously less-structured code, where I'd regard "conditional statements within one function" as 'less structured' and "abstract base class with subclasses" as 'more structured'.

Which approach is better if I want to maximize performance?

Possibly a function pointer: because it's only one or two opcodes to dispatch to the right function, instead of testing several switch statements (assuming that the compiler implements select as "if else if else if else if").

It's also possible that a function pointer isn't as fast: it dispatches to a different location i the code, which may cause slowness due to memory pages and CPU caching; whereas instead a monolithic KeyInputProcess function might have all its code located on the same page of memory.

In either case I doubt whether the performance difference is significant in this case (handling keystrokes).

\$\endgroup\$
2
\$\begingroup\$

are there any performance issues with the conditional functions approach?

No.

Would the checking that takes place every time the function is called have a significant impact on the performance?

No

Which approach is better if I want to maximize performance?

Insignificant difference.

But neither is the method I would use (not for performance but for maintenance).
I would either change the callback used by GLUT as the screen changed, or I would pick the function from a vector:

typedef void (*KEYINPUTPROCESS)(int);
KEYINPUTPROCESS  keyboardProcessingFunctions[] = {
    KeyInputProcessMain, 
    KeyInputProcessMainOptions
};

void KeyInputProcess(int key)
{
    KEYINPUTPROCESS procFunc = keyboardProcessingFunctions[SCREEN];
    return procFunc(key);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.