【问题标题】:Is checking for first character before doing strcmp useful?在执行 strcmp 之前检查第一个字符有用吗?
【发布时间】:2014-07-28 05:35:20
【问题描述】:

以下哪个更有效:

if (strcmp(str1,str2) != 0) {
...
}

if (str1[0]!=str2[0] && strcmp(str1,str2) !=0 ) {
...
}

如果str2 总是唯一的并且可以有多个str1。

【问题讨论】:

  • 你会检查 *s1==*s2 && !strcmp(s1+1, s2+1) 否则你正在对 [0] 进行冗余检查
  • 运行测试并亲自查看。也许您可以向我们提供基准数据。实际上,这完全取决于您拥有的数据类型(有多大)。
  • @tech 你的代码是缓冲区溢出
  • @DavidHeffernan 仅当不知道其中一个字符串的长度大于 0 时,情况并非总是如此。一个典型的用法是将一个变量与一个已知的常量进行比较,即 strcmp("--help",s) 这将是安全的,但如果你要比较 2 个 variables 那么肯定,是的,它需要一个额外检查空字符串!(*s1|*s2) /*true 如果两个字符串都为空*/ 我过去曾对此进行基准测试,以对已排序的常量进行大型二进制搜索;在非典型场景中,额外的第一个字符比较将性能提高了约 10%。

标签: c string strcmp


【解决方案1】:

不需要第二个版本,因为strcmp 通常非常巧妙地实现了一次比较多个字符。

在第二个版本中,由于&& 的短路属性,您可以保存函数调用。您应该根据您的要求对这两个版本进行基准测试,以获得正确的想法。

但我的建议仍然是,不需要您提出的版本 2 (str1[0]!=str2[0] && strcmp(str1,str2) !=0 ),除非 strcmp 被证明是您要求的瓶颈(在分析结果中)并且有证据表明版本 2 性能更好。

【讨论】:

  • 因为调用和跳转是免费的 ...第一个字母比较的重点是它提供内联快速路径...对于gcc和常量字符串第一个版本会更好地优化,但对于一般用途,它有助于拥有一个廉价的快速路径,就像在另一个示例中一样
  • @technosaurus:您假设strcmp 是一个调用,而不是内联/内在的。如果比较第一个字符然后进行分支是正确的,则可以内联 strcmp 来做到这一点。
  • (str1[0]!=str2[0] && str1[0] != '\0' && strcmp(str1,str2) !=0 )如何防止(str1[0]!=str2[0] && strcmp(str1,str2) !=0 )中的UB?正如@David Heffernan 所指出的那样,它确实阻止了*s1==*s2 && !strcmp(s1+1, s2+1) 中的UB,但OP 并没有提出这个建议。
【解决方案2】:
strcmp(str1,str2) !=0

检查第一个字符,如果不相等则返回。所以你不需要专门检查

str1[0]!=str2[0].

您的str1[0]!=str2[0]strcmp(str1,str2) 在第一次检查中所做的相同。

【讨论】:

    【解决方案3】:

    strcmp 开始比较每个字符串的第一个字符。如果它们彼此相等,则继续以下对,直到字符不同或到达终止空字符。

    所以对于第二种情况,额外条件检查字符串的第一个字符似乎没有意义。

    因为strcmp已经完成了(str1[0]!=str2[0])它。

    【讨论】:

    • 许多实现可能选择不逐个字符比较,而是一次比较多个字符。 (通常一次 4 或 8 个字符)
    【解决方案4】:

    正如@Abhineet 所建议的“亲自测试并查看”。

    if (strcmp(str1,str2) != 0)if ((str1[0] != str2[0]) && strcmp(str1,str2) !=0 ) 在传递 C 字符串时功能相同。这当然是一个要求,否则,为什么要比较性能?

    C 并不专注于指定性能,因此如果这种方法在给定机器上的给定编译器上运行得更快,那么对于编译器的下一版本或某些编译器选项更改或不同的字符串数据集可能会更糟。

    但根据我的经验,在多个平台上编写大量使用字符串的代码,这个技巧确实提高了某些机器的性能,并且没有显着降低其他机器的速度。您的结果可能会有所不同。

    与性能的任何线性改进一样,对频繁使用的代码进行细微的代码调整需要深入了解目标机器以知道是否总是更快。

    通常,利用您的编程时间来考虑其他方法可以获得更大的性能改进。

    1) 哈希码
    2) 唯一字符串只需要指针比较
    3) 其他“字符串”结构

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-31
      • 2018-12-03
      相关资源
      最近更新 更多