Rac*_*hel 30 c++ dictionary stdmap std switch-statement
在我的C++应用程序中,我有一些值作为代码来表示其他值.要翻译代码,我一直在讨论使用switch语句或stl映射.开关看起来像这样:
int code;
int value;
switch(code)
{
case 1:
value = 10;
break;
case 2:
value = 15;
break;
}
Run Code Online (Sandbox Code Playgroud)
地图将是一个,stl::map<int, int>并且翻译将是一个简单的查找,其中代码用作键值.
哪一个更好/更有效/更清洁/接受?为什么?
就个人而言,我会使用地图,因为它的使用意味着数据查找 - 使用开关通常表示程序行为的差异.此外,使用地图比使用交换机更容易修改数据映射.
如果性能是一个真正的问题,分析是获得可用答案的唯一方法.如果分支误预测经常发生,则开关可能不会更快.
考虑这一点的另一种方法是将代码和相关值组合到数据结构中是否更有意义,特别是如果代码和值的范围是静态的:
struct Code { int code; int value; };
Code c = ...
std::cout << "Code " << c.code << ", value " << c.value << std::end;
Run Code Online (Sandbox Code Playgroud)
如果你的代码足够连续并且它们的范围允许你使用老式的直接阵列会更好,比如像
int lookup[] = {-1, 10, 15, -1 222};
Run Code Online (Sandbox Code Playgroud)
那么switch语句可以简单地重写
value = lookup [code];
所有其他选择在一定程度上引入额外成本.
它取决于代码是什么以及有多少代码.好的编译器有各种各样的技巧来优化switch语句,其中一些不会直接使用if/then语句.例如,大多数都足够亮以进行简单的数学运算或使用查找/跳转表来表示案例0,1,2或案例3,6,9.
当然有些人没有,很多人很容易被不寻常或不规则的价值观所挫败.此外,如果处理多个案例的代码看起来非常相似,剪切和粘贴可能会导致维护问题.如果您有许多代码,但它们可以通过算法划分为组,您可以考虑使用多个/嵌套的switch语句,例如,而不是:
switch (code) {
case 0x0001: ...
case 0x0002: ...
...
case 0x8001: ...
case 0x8002: ...
...
}
Run Code Online (Sandbox Code Playgroud)
您可以使用:
if (code & 0x8000) {
code &= ~0x8000;
switch (code) {
case 0x0001: ... // actually 0x8001
case 0x0002: ... // actually 0x8002
...
}
}
else {
switch (code) {
case 0x0001: ...
case 0x0002: ...
...
}
}
Run Code Online (Sandbox Code Playgroud)
许多语言解释器以这种方式解码操作码,因为单字节操作码可能具有打包到各种位中的附加信息,并且转录所有可能的组合及其处理程序将是重复且易碎的.另一方面,过多的位修改可能会使编译器无法进行任何优化,并且会适得其反.
除非你确定这是一个真正的性能瓶颈,否则我会避免过早优化:以合理的强大和快速实施的方式为您提供服务.如果您的应用程序运行速度太慢,请对其进行分析并进行相应优化.