比较C中两个字符串的最快方法是什么?

时间:2017-01-02 00:52:02

标签: c string cross-platform c-strings strcmp

为清楚起见,我只讨论空终止字符串。

我熟悉使用strcmp在C中进行字符串比较的标准方法。但我觉得它很慢而且效率低下。

我不一定在寻找最简单的方法,但效率最高。

当底层代码保持跨平台时,是否可以进一步优化当前比较方法(strcmp)?

如果strcmp无法进一步优化,那么在没有strcmp的情况下我可以执行字符串比较的最快方法是什么?

当前用例:

  • 确定两个任意字符串是否匹配
  • 字符串不会超过4096字节,也不会少于1字节
  • 在相同的代码/库中分配/取消分配和比较字符串
  • 比较完成后,我将字符串传递给另一个C库,该库需要格式为标准的空终止格式
  • 系统内存限制不是一个大问题,但我会排队等待成千上万的此类字符串进行比较
  • 字符串可能包含高ascii字符集或UTF-8字符但是出于我的目的,我只需要知道它们是否匹配,内容不是问题
  • 应用程序在x86上运行,但也应在x64上运行

引用当前的strcmp()实现:

编辑:澄清解决方案不需要修改strcmp。

编辑2:为此用例添加了特定示例。

1 个答案:

答案 0 :(得分:4)

我担心strcmp()引用内容既不准确又不相关:

  • 它不准确,因为它使用char类型而不是C11标准中指定的unsigned char类型来比较字符:

      

    7.24.4比较功能

         

    比较函数memcmpstrcmpstrncmp返回的非零值的符号由第一对字符值之间的差异符号决定(两者都被解释为unsigned char),它们在被比较的对象中有所不同。

  • 这是无关紧要的,因为现代编译器使用的实际实现要复杂得多,使用手工编码的汇编语言进行内联扩展。

任何通用实现都可能不太理想,特别是如果编码为跨平台保持可移植性。

如果您的计划的瓶颈是比较字符串,请参考以下几个方向。

  • 分析您的算法,尝试找到减少比较次数的方法:例如,如果您在数组中搜索字符串,对该数组进行排序并使用二进制搜索会大大减少比较次数。
  • 如果您的字符串是在许多不同位置使用的令牌,请分配这些令牌的唯一副本并将其用作标量值。当且仅当指针相等时,字符串才相等。我一直使用哈希表在编译器和解释器中使用这个技巧。
  • 如果您的字符串具有相同的已知长度,则可以使用memcmp()代替strcmp()memcmp()strcmp()更简单,并且可以在已知字符串正确对齐的位置更有效地实现。

编辑,如果提供了额外的信息,您可以在字符串中使用这样的结构:

typedef struct string_t {
    size_t len;
    size_t hash;  // optional
    char str[];   // flexible array, use [1] for pre-c99 compilers
} string_t;

您可以这种方式分配此结构:

string_t *create_str(const char *s) {
    size_t len = strlen(s);
    string_t *str = malloc(sizeof(*str) + len + 1;
    str->len = len;
    str->hash = hash_str(s, len);
    memcpy(str->str, s, len + 1);
    return str;
}

如果您可以对所有字符串使用这些 str ,则可以通过首先比较长度或哈希值来大大提高匹配效率。您仍然可以将str成员传递给您的库函数,它正确地以空值终止。