改变不区分大小写的字符串比较性能

Posted

技术标签:

【中文标题】改变不区分大小写的字符串比较性能【英文标题】:Varying case-insensitive string comparisons performance 【发布时间】:2015-03-30 16:58:03 【问题描述】:

所以,我的博士项目依赖于我已经构建了近 3 年的软件。它运行,稳定(它不会崩溃或抛出异常),我正在使用它的发布版本。而且我开始意识到性能会受到巨大影响,因为我过于依赖 boost::iequals。 我知道,关于这个有很多关于这个的,这不是关于如何去做的问题,而是为什么会发生这种情况。 考虑以下几点:

#include <string.h>
#include <string>
#include <boost/algorithm/string.hpp>

void posix_str ( )

    std::string s1 = "Alexander";
    std::string s2 = "Pericles";
    std::cout << "POSIX strcasecmp: " << strcasecmp( s1.c_str(), s2.c_str() ) << std::endl;


void boost_str ( )

    std::string s1 = "Alexander";
    std::string s2 = "Pericles";
    std::cout << "boost::iequals: " << boost::iequals( s1, s2 ) << std::endl;


int main ( )

    posix_str();
    boost_str();
    return 0;

我通过 valgrind 和 cachegrind 进行了测试,令我惊讶的是,boost 比本地 posix 或 std(似乎使用相同的 posix)方法慢 4 倍。四次,现在已经很多了,即使考虑到 C++ 提供了一个很好的安全网。这是为什么?我真的希望其他人运行它,并向我解释是什么让这样的性能受到影响。是所有分配(似乎来自调用者映射)。 我不反对 boost,我喜欢它并在任何地方和任何地方使用它。 编辑:This graph shows what I mean

【问题讨论】:

发布演示您的问题的测试代码。此代码无法帮助我们理解您对原始代码所做的事情,而且我不会相信您的话only,没有看到显示问题的代码。所以显示代码以及你如何测量它。 @Nawaz 没有问题。显示了测试代码,boost::iequals 似乎比 strcasecmp 慢 4 倍,我试图了解原因。 它在哪里向我们显示它慢了 4 倍?你能展示证明这一点的代码吗? @NathanOliver 添加了来自 kcachegrind 的输出图 您是否只运行了一次以获得这些结果?你有没有使用任何优化?理想情况下,您需要运行这些函数几千次才能获得良好的平均执行速度。 【参考方案1】:

Boost::iequals 可识别区域设置。从它的定义here 可以看出,它采用一个可选的第三个参数,默认为default-constructedstd::locale,它代表std::locale::global 设置的当前全局C++ 语言环境。

这或多或少意味着编译器无法提前知道要使用哪个语言环境,这意味着将间接调用某个函数将每个字符转换为小写当前语言环境。

另一方面,documentation 的 strcasecmp 声明:

在 POSIX 语言环境中,strcasecmp() 和 strncasecmp() 的行为就像字符串已转换为小写,然后执行字节比较一样。结果在其他语言环境中未指定。

这意味着语言环境是固定的,因此您可以期待它得到大量优化。

【讨论】:

谢谢 sbabbi,这很有意义!

以上是关于改变不区分大小写的字符串比较性能的主要内容,如果未能解决你的问题,请参考以下文章

Java UUID是不是区分大小写

Java UUID是不是区分大小写

与一堆字符串比较不区分大小写

如何进行不区分大小写的字符串比较?

Go中不区分大小写的字符串比较

mysql查询时不区分大小写