Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make efficient C++ jump table?

I'm beginner to C++ and I have implemented the following simple jump table, but was wondering if I'm doing it the right way. Is there anyway I can improve the following code?

The following code is using a dictionary (I'm from a C# background) to store functions' pointers.

#include <cstdio>
#include <iostream>
#include <string>
#include <unordered_map>

using namespace std;

void Zero() { printf("Zero\n"); }
void One() { printf("One\n"); }   
void Two() { printf("Two\n"); }
void Three() { printf("Three\n"); }

string prompt()
{
    printf("Enter number from 0 to 3 or q to quit:\n");
    string line;
    getline(cin, line);

    return line;
}

int main(int argc, const char * argv[]) {

    unordered_map<string, void(*)()> map;

    map["0"] = Zero;
    map["1"] = One;
    map["2"] = Two;
    map["3"] = Three;

    while (true) {
        string c = prompt();
        if (c == "q") break;

        map[c]();
    }
    return 0;
}
like image 968
idemery Avatar asked Dec 07 '22 23:12

idemery


2 Answers

How about a switch statement?

switch (c) {
   case 0:
      printf("Zero\n"); break;
   case 1:
      printf("One\n"); break;
   case 2:
      printf("Two\n"); break;
   case 3:
      printf("Three\n"); break;
   default:
      break;
}
like image 125
Nikolas Charalambidis Avatar answered Dec 21 '22 05:12

Nikolas Charalambidis


There's not much you can do to make your code "faster" without going for the switch solution which breaks the original idea of having an array of functions. If you only gonna use 'characters' such as '0' => '9', 'a' => 'z' you could dodge the memory allocation needed for the string, and you could also initialize your map with an initializer_list, and you could also make such array const static if that's viable.

Here goes my "optimized" code if it helps.

inline char prompt() //this function will probably 900% be inlined even if you don't specify the inlike keyword
{
    printf("Enter number from 0 to 3 or q to quit:\n");
    char v;
    while (!(std::cin >> v)); //Just to make sure we get valid input
    return v;
}

int main()
{
    static const std::unordered_map<char, void(*)()> mymap = 
    {
        { '0' , Zero },
        { '1' , One },
        { '2' , Two },
        { '3' , Three }
    };

    while(1)
    {
        auto it = mymap.find(prompt());

        // Without this check, your program will crash if input is invalid.
        if (it != mymap.end()) 
        {
            it->second();
            break;
        }
    }

    return 0;
}
like image 39
Jts Avatar answered Dec 21 '22 03:12

Jts