【问题标题】:Most efficient const char* comparison being case insensitive最有效的 const char* 比较不区分大小写
【发布时间】:2012-05-24 04:02:02
【问题描述】:

谁能告诉我比较两个恒定字符星的最有效方法吗?

#include <iostream>
#include <string>

int main()
{
    const char* value1 = "hello";
    const char* value2 = "HELLO";
    const char* possibility = NULL;


    if(stricmp(value1, value2)==0)
    {
        std::cout <<"\nThey Match!!!!!" << std::endl;
    }
    else{std::cout << "\nThey dont match :("<< std::endl;}

    return 0;
}

我使用了以下标准函数,但我知道这不是最有效的方法?

除了 stricmp 不能处理 NULL 之外,在我的情况下这有可能发生。

那么还有其他对性能有好处的替代方案吗?

提前致谢

【问题讨论】:

  • 你怎么“知道”这不是最有效的方法?你衡量过替代品吗?实际上,您是否测量了 this 方法?您的性能要求是什么?
  • 为什么你认为它没有效率?这将取决于 stricmp 是如何实现的,这将是特定于平台的,并且通常它们都得到了很好的优化。
  • using namespace std; 在该命名空间中不使用 everything 的效率远低于 strcmp 所做的任何事情。
  • 这是一个基本的例子。 . .插图 。 . .我无法粘贴我的实际来源,这将非常“难以”看到我的问题的主要焦点。
  • 不过会更有趣 ;-)

标签: c++ performance optimization


【解决方案1】:

没有有效的方法来比较两个字符串。

有几种方法可以改进基本的stricmp(),如果它在个人资料中显示得非常高(我在真实的应用程序中看到过)。您可能会发现大部分成本在tolower() 中,这是对每个字符调用的函数,用于在比较之前将其从大写转换为小写。这个函数调用的开销,加上它的函数体的成本,加起来会很长,因为它必须是区域敏感的,并且要处理像 Ö 这样的字母。如果您知道您的比较只会在一种语言环境中执行(即仅以英语),那么您可以通过构建一个 256 个字符的 ASCII 查找表并手动实现 stricmp() 来加速 tolower()。

使用 GCC,如果您知道您的目标是支持 SSE3 的 CPU,您还可以指定 -msse3 命令行开关,它会为字符串比较生成稍微更有效的机器指令。但是,它主要有助于区分大小写

在我的工作中,任何需要比较大量常量字符串的算法,而不是使用实习生或符号来表示此类标识符,都被认为是代码异味。在一个项目中,分析表明大约 7% 的 CPU 时间花费在 stricmp 内的 tolower() 中。这实际上是每个数据中心的 100 台机器中的 7 台除了将大写字母转换为小写字母之外什么都不做。

【讨论】:

  • Crashworks 感谢您的洞察力,我目前正在研究开关,非常有趣地解决了我遇到的问题。有趣的是,您指出了 .tolower() 成本以及可以降低成本的方法.谢谢你:)
  • @GgGg 您应该在您的应用程序上运行一个采样分析器,并在您采取极端措施之前确保tolower() 确实是一个性能问题。这并不总是一个问题。这在很大程度上取决于您使用的编译器以及您的特定使用模式。
  • 再次感谢,看来 .tolower 是我的主要杀手。老实说,我认为该编译器切换不合适,我有 2 天的时间,这是我一直在寻找的关键。再次感谢!
  • @GgGg 如果您要设置该标志,请尝试同时设置-mfpmath=sse,这将加快您的所有浮点数学运算速度。
【解决方案2】:

stricmp 可能比您自己编写的任何代码都快,除非您知道这将成为您程序性能的瓶颈,否则您不应该打扰。

【讨论】:

  • 我参与过许多项目,其中 stricmp() 是主要的性能瓶颈(配置文件中的 top 函数),并且通过编写自定义 stricmp( )。 (一开始在代码审查期间捕获不必要的比较字符串并没有得到改善,但遗憾的是,并不是每个程序员都意识到它们的成本有多大。)
  • 我同意这是一个代价高昂的实现,因为对它的调用数量很大
  • 信任系统 API 并不能让程序员变得更好。它们是忙碌的人写的,就像你一样。
猜你喜欢
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-18
相关资源
最近更新 更多