C++ 安全切换语句的优化

C++ 安全切换语句的优化,c++,switch-statement,C++,Switch Statement,我需要使用经常调用的开关优化一个函数:(这个函数的思想非常简单) StringTable*FastTableOf2(常量字符和搜索){ 开关(计数){ 案例256: 返回*(子项+*(字节*)&查找); 案例10: if(seek!=键[9]) ... 案例2: if(seek!=键[1]) 案例1: if(seek==键[0]) 返回子项[0]; 否则{ } 其他的 返回儿童[1]; 其他的 返回儿童[2]; ... 其他的 返回儿童[9]; } 返回0; } 我考虑检查Count是否为25

我需要使用经常调用的开关优化一个函数:(这个函数的思想非常简单)

StringTable*FastTableOf2(常量字符和搜索){
开关(计数){
案例256:
返回*(子项+*(字节*)&查找);
案例10:
if(seek!=键[9])
...
案例2:
if(seek!=键[1])
案例1:
if(seek==键[0])
返回子项[0];
否则{
}
其他的
返回儿童[1];
其他的
返回儿童[2];
...
其他的
返回儿童[9];
}
返回0;
}
我考虑检查
Count
是否为256,然后执行
return*(Children+*(byte*)&seek)
如果没有,则执行
转到case[Count]
而不检查值是否在10-1范围内。(
计数
只能为256或介于1和10之间)

有没有办法告诉编译器只需执行
jmp
即可在开关中添加标签,而不必检查它是否在范围内?
我知道这种优化非常小,但这里每个百分比都很重要。

对于高度关键的代码部分,我根本不会使用
开关,而是使用跳转表

在跳转表中设置函数指针数组。这些函数可以做一些非常简单的事情,比如返回一个立即值,或者做一些更复杂的事情。数组中有N个元素,其中N是您可以
打开的最大可能值

在设置跳转表时,您将提前填充数组,可能是在程序启动时。每个条目要么指向一个实函数,要么指向某种“未处理”的处理程序

更换
开关
非常简单:

StringTable<T> *FastTableOf2( const char &seek ) {

  return (mJumpTable[Count])(seek);
}
StringTable*FastTableOf2(常量字符和搜索){
返回(mJumpTable[Count])(seek);
}

你不会比这更快了。

我认为交换机的实现已经是一次尝试优化, 因为代码似乎相当于:

StringTable<T> *FastTableOf2(const char& seek)
{
    if (Count == 256) {
        return *(Children + *(byte*)&seek);
    }
    assert(1 <= Count && Count <= 10);
    for (auto c = Count; c != 0; --c) {
        if (seek == Keys[c - 1]) {
            return Children[c - 1];
        } 
    }
    return nullptr;
}

如果将
案例1
更改为
默认值
,是否有帮助?(不是答案,因为我现在无法测试)。@MikeSeymour编译器将缩小表并执行另一个
jmp
。(如果不在范围内)尝试过,但谢谢。请注意,这里的
开关
对于用作
标签的
案例
来说很棘手uncase'(如展开循环)可能会产生大量重复代码。也许您可以进行更改以减少调用此方法的频率。你可以使用一些记忆…@MikeSeymour:
默认值
应该是
返回0
,正如我所理解的(根据OP,不应该调用)。有些人告诉我做类似的事情。调用函数不是更慢吗?我现在就试试。它与您正在查找的
jmp
相同。但是它使用push-seek和push-this-address,然后是jmp。我想我有一个想法,没有追求。您正在直接寻址数组中的函数指针。我认为编译器(may)已经通过跳转表实现了
开关
,在这种情况下。我在代码中展开了循环。(性能更好)我已经用可能的优化编辑了我的答案。
StringTable<T> *FastTableOf2(const char& seek)
{
    if (Count == 256) {
        return *(Children + *(byte*)&seek);
    }
    assert(1 <= Count && Count <= 10);
    for (auto c = Count; c != 0; --c) {
        if (seek == Keys[c - 1]) {
            return Children[c - 1];
        } 
    }
    return nullptr;
}
StringTable<T> *FastTableOf2(const char &seek ) {
    switch (char(Count)) {
        default: // Count >= 10 
        case 10: if (seek != Keys[9]) {
        ...
        case 2: if (seek != Keys[1]) {
        case 1:
            if (seek != Keys[0]) { return nullptr; } else { return Children[0]; }
            } else { return Children[1]; } // Count == 2
            } else { return Children[2]; } // Count == 3
            ...
            } else { return Children[9]; } // Count == 10
        // char(256) == '\0'
        case char(256): return *(Children + *(byte*)&seek);
    }
}