我有一个关键的代码部分,它检查许多字符串中的每个字符,以确保它落在可接受的范围内。
有什么方法可以在不分支的情况下执行此类过滤?
...
int i, c;
int sl = strnlen(s, 1023);
for( i = 0; i < sl; i++ ) {
c = s[i];
if( c < 68 || c > 88 )
return E_INVALID;
}
if( 0 == i )
return E_INVALID;
... do something with s ...
我认为使用按位运算进行某种过滤可能是可能的,但实际上我看不出如何做到这一点。按位 AND 与 95 修剪范围降至 0-31,64-95。如果不引入 if 测试,我看不到如何进步,从而使跳过分支的想法变得空白。
假设你的字符串真的是无符号字符,而不是整数,你可以有一个 256 字节的不可接受的字符查找表,这将使你的测试 if(table[s[i]]) { return E_INVALID; }
但是,如果您正在尝试加速关键功能,您应该做其他事情以获得更大的回报。 首先,您可以完全跳过 strnlen,并在 0 字符上终止循环。仅此一项就可能使您获得 2 倍。 接下来,将循环展开 10 倍左右,这应该得到另一个系数 2。
可以使用按位运算进行过滤。尝试。。。
c & 68 & ~88;
对于大于边界的值,这应始终返回零,对于边界内的值,应始终返回非零值。
订单也是必要的...
CHAR & LowerBound & ~UpperBound
翻转界限会导致错误的行为