C++ 将快速 1、2、3 整数映射到硬编码字符?

C++ map fast 1,2,3 integers to hardcoded chars?

我需要将 int 值 1、2、3 映射到字符 'C'、'M'、'A'

什么是最快的方式(这将在 24/7 期间每秒调用 100 次)?

一个宏或一个内联函数和一堆 ?: 运算符或 ifs 或 switch?还是数组?

A​​ lookup-table 似乎是最明显的方法,因为它也是 branch-free:

constexpr char map(std::size_t i) {
  constexpr char table[] = "0CMA";
  // if in doubt add bounds checking for i, but it will cost performance
  return table[i];
}

观察到通过优化,查找 table boils down 到整数常量。

编辑:如果你没有我那么懒,你可以去掉一条额外的指令,这样指定查找table:

  constexpr char table[] = {0, 'M', 'C', 'A'};

我的建议:(char)(0x414D4300 >> (i * 8))

你可以写 (('C' << 8) | ('M' << 16) | ('A' << 24)).

而不是 0x414D4300

只有实际测试才能告诉您这是否比位掩码的答案更快。

如果它每秒仅运行 100 次,那么无论如何您都是在追逐一条红鲱鱼。即使您以最愚蠢的方式编写此部分,它似乎也比程序的其余部分快一百万倍。

您正在过早地优化您的代码。让我证明一下。这是最简单、最慢但仍然合理的方法:

#include <map>

char map(int i) {
    std::map<int, char> table;
    table[1] = 'C';
    table[2] = 'M';
    table[3] = 'A';

    return table[i];
}

generates数百行汇编指令。

让我们为一百万个元素计时:

#include <iostream>
#include <map>
#include <chrono>
#include <cstdlib>
#include <vector>

char map(int i) {
    std::map<int, char> table;
    table[1] = 'C';
    table[2] = 'M';
    table[3] = 'A';

    return table[i];
}

int main() {
    int const count = 1'000'000;
    std::vector<int> elms(count);
    
    std::srand(0); // I know that rand is no good, but it's OK for this example
    for (int i = 0; i < count; ++i) {
        elms[i] = std::rand() % 3 + 1;
    }

    auto beg = std::chrono::high_resolution_clock::now();
    volatile int do_not_optimize;
    for (int i = 0; i < count; ++i) {
        do_not_optimize = map(elms[i]);
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - beg);
    std::cout << "Duration: " << duration.count() << " ms" << std::endl;
}

这是我电脑上的输出,旁边还有很多其他程序运行:

Duration: 246 ms

这个糟糕的实施在糟糕的条件下仍然可以满足您 40'650 倍以上的需求。我敢打赌,您在代码库的其他地方还有更多需要担心的地方。记得把它做对,只有当它还不够快时才让它变快。