gpt4 book ai didi

c++ - 在 C++ 中将十六进制转换为整数的最快方法是什么?

转载 作者:IT王子 更新时间:2023-10-28 23:27:53 24 4
gpt4 key购买 nike

我正在尝试尽快将十六进制 char 转换为整数。

这只有一行:int x = atoi(hex.c_str);

有没有更快的方法?

在这里,我尝试了一种更动态的方法,速度略快。

int hextoint(char number) {
if (number == '0') {
return 0;
}
if (number == '1') {
return 1;
}
if (number == '2') {
return 2;
}
/*
* 3 through 8
*/
if (number == '9') {
return 9;
}
if (number == 'a') {
return 10;
}
if (number == 'b') {
return 11;
}
if (number == 'c') {
return 12;
}
if (number == 'd') {
return 13;
}
if (number == 'e') {
return 14;
}
if (number == 'f') {
return 15;
}
return -1;
}

最佳答案

比 OP 的 if-else 渲染速度更快的建议解决方案:

  • 无序 map 查找表

如果您的输入字符串始终是十六进制数字,您可以将查找表定义为 unordered_map:

std::unordered_map<char, int> table {
{'0', 0}, {'1', 1}, {'2', 2},
{'3', 3}, {'4', 4}, {'5', 5},
{'6', 6}, {'7', 7}, {'8', 8},
{'9', 9}, {'a', 10}, {'A', 10},
{'b', 11}, {'B', 11}, {'c', 12},
{'C', 12}, {'d', 13}, {'D', 13},
{'e', 14}, {'E', 14}, {'f', 15},
{'F', 15}, {'x', 0}, {'X', 0}};

int hextoint(char number) {
return table[(std::size_t)number];
}
  • 查找表作为用户 constexpr 文字 (C++14)

或者,如果您想要更快的东西而不是 unordered_map,您可以将新的 C++14 工具与用户文字类型一起使用,并在编译时将您的表定义为文字类型:

struct Table {
long long tab[128];
constexpr Table() : tab {} {
tab['1'] = 1;
tab['2'] = 2;
tab['3'] = 3;
tab['4'] = 4;
tab['5'] = 5;
tab['6'] = 6;
tab['7'] = 7;
tab['8'] = 8;
tab['9'] = 9;
tab['a'] = 10;
tab['A'] = 10;
tab['b'] = 11;
tab['B'] = 11;
tab['c'] = 12;
tab['C'] = 12;
tab['d'] = 13;
tab['D'] = 13;
tab['e'] = 14;
tab['E'] = 14;
tab['f'] = 15;
tab['F'] = 15;
}
constexpr long long operator[](char const idx) const { return tab[(std::size_t) idx]; }
} constexpr table;

constexpr int hextoint(char number) {
return table[(std::size_t)number];
}

Live Demo

基准测试:

我使用 Nikos Athanasiou 最近发布在 isocpp.org 上的代码运行基准测试。作为 C++ 微基准测试的建议方法。

比较的算法有:

1. OP的原版if-else:

long long hextoint3(char number) {
if(number == '0') return 0;
if(number == '1') return 1;
if(number == '2') return 2;
if(number == '3') return 3;
if(number == '4') return 4;
if(number == '5') return 5;
if(number == '6') return 6;
if(number == '7') return 7;
if(number == '8') return 8;
if(number == '9') return 9;
if(number == 'a' || number == 'A') return 10;
if(number == 'b' || number == 'B') return 11;
if(number == 'c' || number == 'C') return 12;
if(number == 'd' || number == 'D') return 13;
if(number == 'e' || number == 'E') return 14;
if(number == 'f' || number == 'F') return 15;
return 0;
}

<强>2。紧凑的 if-else,由 Christophe 提出:

long long hextoint(char number) {
if (number >= '0' && number <= '9') return number - '0';
else if (number >= 'a' && number <= 'f') return number - 'a' + 0x0a;
else if (number >= 'A' && number <= 'F') return number - 'A' + 0X0a;
else return 0;
}

3.更正了 g24l 提出的同时处理大写字母输入的三元运算符版本:

long long hextoint(char in) {
int const x = in;
return (x <= 57)? x - 48 : (x <= 70)? (x - 65) + 0x0a : (x - 97) + 0x0a;
}

4.查找表(unordered_map):

long long hextoint(char number) {
return table[(std::size_t)number];
}

其中 table 是前面显示的无序映射。

5.查找表(用户 constexpr 文字):

long long hextoint(char number) {
return table[(std::size_t)number];
}

其中 table 是用户定义的文字,如上所示。

实验设置

我定义了一个将输入的十六进制字符串转换为整数的函数:

long long hexstrtoint(std::string const &str, long long(*f)(char)) {
long long ret = 0;
for(int j(1), i(str.size() - 1); i >= 0; --i, j *= 16) {
ret += (j * f(str[i]));
}
return ret;
}

我还定义了一个用随机十六进制字符串填充字符串 vector 的函数:

std::vector<std::string>
populate_vec(int const N) {
random_device rd;
mt19937 eng{ rd() };
uniform_int_distribution<long long> distr(0, std::numeric_limits<long long>::max() - 1);
std::vector<std::string> out(N);
for(int i(0); i < N; ++i) {
out[i] = int_to_hex(distr(eng));
}
return out;
}

我创建了分别填充有 50000、100000、150000、200000 和 250000 个随机十六进制字符串的 vector 。然后对于每个算法,我运行 100 次实验并平均时间结果。

编译器是 GCC 5.2 版,带有优化选项 -O3

结果:

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

讨论

从结果我们可以得出结论,对于这些实验设置,建议的表格方法优于所有其他方法。 if-else 方法是迄今为止最差的,因为 unordered_map 尽管它赢得了 if-else 方法,但它比其他提议的方法慢得多。

CODE

编辑:

stgatilov 提出的方法的结果,按位运算:

long long hextoint(char x) {
int b = uint8_t(x);
int maskLetter = (('9' - b) >> 31);
int maskSmall = (('Z' - b) >> 31);
int offset = '0' + (maskLetter & int('A' - '0' - 10)) + (maskSmall & int('a' - 'A'));
return b - offset;
}

enter image description here

编辑:

我还针对表格方法测试了来自 g24l 的原始代码:

long long hextoint(char in) {
long long const x = in;
return x < 58? x - 48 : x - 87;
}

请注意,此方法不处理大写字母ABCDEF

结果:

enter image description here

表格方法仍然渲染得更快。

关于c++ - 在 C++ 中将十六进制转换为整数的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34365746/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com