如何制作高效的C++跳台
How to make efficient C++ jump table?
我是C++初学者,我已经实现了以下简单的跳转表,但想知道我是否以正确的方式做。无论如何我可以改进以下代码吗?
以下代码使用字典(我来自 C# 背景)来存储函数的指针。
#include <cstdio>
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
void Zero() { printf("Zeron"); }
void One() { printf("Onen"); }
void Two() { printf("Twon"); }
void Three() { printf("Threen"); }
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;
}
switch 语句怎么样?
switch (c) {
case 0:
printf("Zeron"); break;
case 1:
printf("Onen"); break;
case 2:
printf("Twon"); break;
case 3:
printf("Threen"); break;
default:
break;
}
如果不采用开关解决方案,你就无能为力,无法使代码"更快",这打破了拥有函数数组的原始想法。如果你只要使用"字符",如'0' =>'9', 'a' => 'z',你可以躲避字符串所需的内存分配,你也可以用一个initializer_list初始化你的map,如果可行的话,你也可以使这样的数组常量静态。
如果有帮助,这是我的"优化"代码。
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;
}
请求为您的效率案例提供更多细节。您的意思是内存/CPU 周期/直通吗?根据您的代码:
- 它不容易出错(使用
auto it = map.find(key);
函数搜索和检查输出it != map.end()
值,因此不会创建新元素) - 对于字符串键类型来说已经足够了
- 通过将函数指针替换为
std::function<void()>
,您可以轻松变得更加灵活
就更底层的控制而言,您可以自定义哈希函数和自定义哈希表实现。在某些数据上,考虑std::map
或排序std::vector
选项可能是有用的。
由于静态查找速度很快,因此无论编译器如何,这都将执行得非常好。跳转表因编译器而异。我会使用以下代码,可能有些人会反对这global
因为不好。但在评论之前,请对此进行评估
string prompt()
{
printf("Enter number from 0 to 3 or q to quit:n");
string line;
getline(cin, line);
return line;
}
enum Choice = {ZERO = 0, ONE, TWO, THREE};
static char *choice_str[] = {
"Zero",
"One",
"Two",
"Three"
};
int main(int argc, const char * argv[]) {
while (true) {
string c = prompt();
if (c == "q")
{
break;
}
else {
assert(atoi(c) >= Choice::ZERO && atoi(c) <=Choice::THREE);
printf("%sn", choice_str[atoi(c)]);
}
}
相关文章: