如何快速比较字符串与许多预定义的字符串?

时间:2013-11-30 14:14:10

标签: c++ performance

我需要快速将请求的路径与预定义的常量进行比较,如下所示:

if (path == "/admin")
    ...
else if (path == "/something-else")
    ...
else if (path == "/something-else2")
else
    ...

然而,名单非常庞大。这里的问题是速度。我需要很快完成。
你会怎么做呢?

6 个答案:

答案 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语句复制/包含到主程序中。

为了速度,很难击败那些代码。