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

时间:2015-03-30 16:58:03

标签: c++ string c++11 boost

所以,我的博士项目依赖于我已经建立了近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 ++提供了一个很好的安全网。这是为什么?我真的希望其他人能够运行这个,并向我解释一下这样的性能如何受到影响。是所有的分配(似乎来自呼叫者地图)。 我并不喜欢提升,我喜欢它并随处随地使用它。 编辑:This graph shows what I mean

1 个答案:

答案 0 :(得分:7)

Boost::iequals可识别区域设置。正如您从其定义here中所看到的,它采用了一个可选的第三个参数,默认为default-constructed std::locale,表示当前的全局C ++语言环境,由std::locale::global设置。

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

另一方面,strcasecmp {{1}}表示:

  

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

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