Dense Integer Dispatch: switch vs. Function-Pointer Table

Question 45 / 51 Correct so far: 0 (0 answered)

Snippet A

Switch Dispatch

int dispatch(uint8_t op, int val) {
    switch (op) {
        case  0: return val + 1;
        case  1: return val - 1;
        case  2: return val * 2;
        case  3: return val >> 1;
        case  4: return val ^ 0xFF;
        case  5: return val & 0x0F;
        case  6: return val | 0x80;
        case  7: return ~val;
        case  8: return val + 7;
        case  9: return val - 3;
        case 10: return val * 3;
        case 11: return val >> 2;
        case 12: return val ^ 0xAA;
        case 13: return val & 0xF0;
        case 14: return val | 0x40;
        case 15: return val + val;
        default: return val;
    }
}

for (uint8_t op : OPCODES)
    acc = dispatch(op, acc);
Snippet B

Table Dispatch

using OpFn = int(*)(int);
static const std::array<OpFn, kNumOpcodes> OP_TABLE = {{
    [](int v){ return v + 1;    },
    [](int v){ return v - 1;    },
    [](int v){ return v * 2;    },
    [](int v){ return v >> 1;   },
    [](int v){ return v ^ 0xFF; },
    [](int v){ return v & 0x0F; },
    [](int v){ return v | 0x80; },
    [](int v){ return ~v;       },
    [](int v){ return v + 7;    },
    [](int v){ return v - 3;    },
    [](int v){ return v * 3;    },
    [](int v){ return v >> 2;   },
    [](int v){ return v ^ 0xAA; },
    [](int v){ return v & 0xF0; },
    [](int v){ return v | 0x40; },
    [](int v){ return v + v;    },
}};

for (uint8_t op : OPCODES)
    acc = OP_TABLE[op](acc);
Shared test data (shared-setup)
constexpr int kOps = 65536;
constexpr int kNumOpcodes = 16;

static std::vector<uint8_t> makeOpcodes() {
    std::mt19937 rng(99);
    std::uniform_int_distribution<int> dist(0, kNumOpcodes - 1);
    std::vector<uint8_t> ops(kOps);
    for (auto& op : ops) op = static_cast<uint8_t>(dist(rng));
    return ops;
}

static const std::vector<uint8_t> OPCODES = makeOpcodes();

Which snippet is faster?

Select the correct answer(s)