我需要快速将请求的路径与预定义的常量进行比较,如下所示:
if (path == "/admin")
...
else if (path == "/something-else")
...
else if (path == "/something-else2")
else
...
然而,名单非常庞大。这里的问题是速度。我需要很快完成。
你会怎么做呢?
答案 0 :(得分:3)
使其成为整数比较。使用哈希函数,它从您的字符串中生成一个整数。整数比较快得多。然后只需使用静态查找表或开关快速选择所需的操作。
一个非常好的快速哈希函数是MurmurHash2,它的碰撞率也很低 离线生成pathes的值,然后将路径与它们进行比较:
switch (MurmurHash2(path.c_str(), path.size(), MAGIC_SEED_CONSTANT)
{
case 0xFA01FDF1: /* /admin */
...
break;
case 0xCC040A12: /* /something-else */
...
break;
case 0xBDF450A3: /* /something-else2 */
...
break;
default:
...
}
答案 1 :(得分:2)
如果您的预定义字符串在运行时都已知,则可以尝试使用boost :: spirit。它将编译时字符串构建为trie,然后使用它进行解析。在成功匹配时,它将执行相关的语义操作。我认为Roman Numeral例子可能非常适合这种要求。
如果在运行时未知预定义的字符串,则可以尝试运行时构建的trie。我在Keyword Matching Blog Entry处的示例代码中做了类似的事情。
答案 2 :(得分:1)
您可以将路径名的字符串文字存储为std :: set,并使用其方法find ti来确定给定路径是否存在于集合中。
答案 3 :(得分:1)
一种非常简单的方法是将所有字符串连接成一个字符串,并使用一次调用std :: string :: find来查看输入是否在任何地方都匹配。
答案 4 :(得分:1)
另一个解决方案是在排序的vector
中存储要比较的所有路径,然后执行std::lower_bound
以查找事件。
然后,您可以切换索引,即比哈希键更少的神秘值。
答案 5 :(得分:1)
这与Raymond的答案相似,但没有使用Boost。
假设您的字符串是事先给出的。 AA,AB,BA,BB。 你可以写一个小程序来对列表进行排序,然后递归打印出一个看起来像这样的嵌套switch语句,这是一个硬编码的trie:
switch(path[0]){
break; case 'A': switch(path[1]){
break; case 'A': switch(path[2]){
break; case '\0':; // "AA" found
break; default:
// no match
}
break; case 'B': switch(path[2]){
break; case '\0':; // "AB" found
break; default:
// no match
}
break; default:
// no match
}
break; case 'B': switch(path[1]){
break; case 'A': switch(path[2]){
break; case '\0':; // "BA" found
break; default:
// no match
}
break; case 'B': switch(path[2]){
break; case '\0':; // "BB" found
break; default:
// no match
}
break; default:
// no match
}
break; default:
// no match
}
然后将嵌套的switch语句复制/包含到主程序中。
为了速度,很难击败那些代码。