改变不区分大小写的字符串比较性能
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,这很有意义!以上是关于改变不区分大小写的字符串比较性能的主要内容,如果未能解决你的问题,请参考以下文章