可变的不区分大小写的字符串比较性能
Varying case-insensitive string comparisons performance
所以,我的 phd 项目依赖于我已经构建了将近 3 年的软件。它 运行s,它稳定(它不会崩溃或抛出异常),我正在玩它的发布版本。而且我开始意识到性能受到了巨大的影响,因为我太依赖 boost::iequals。
我知道,关于这个有很多关于 SO 的问题,这不是关于如何做的问题,而是为什么会发生这种情况。
考虑以下因素:
#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
Boost::iequals
是区域设置感知的。从它的定义 here it takes an optional third parameter that is defaulted to a default-constructed std::locale
中可以看出,它表示当前全局 C++ 语言环境,由 std::locale::global
设置。
这或多或少意味着编译器无法提前知道将使用哪个语言环境,这意味着将间接调用某个函数将每个字符转换为小写在当前语言环境中。
另一方面,strcasecmp
的 documentation 指出:
In the POSIX locale, strcasecmp() and strncasecmp() shall behave as if the strings had been converted to lowercase and then a byte comparison performed. The results are unspecified in other locales.
这意味着语言环境是固定的,因此您可以预期它会被大量优化。
所以,我的 phd 项目依赖于我已经构建了将近 3 年的软件。它 运行s,它稳定(它不会崩溃或抛出异常),我正在玩它的发布版本。而且我开始意识到性能受到了巨大的影响,因为我太依赖 boost::iequals。 我知道,关于这个有很多关于 SO 的问题,这不是关于如何做的问题,而是为什么会发生这种情况。 考虑以下因素:
#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
Boost::iequals
是区域设置感知的。从它的定义 here it takes an optional third parameter that is defaulted to a default-constructed std::locale
中可以看出,它表示当前全局 C++ 语言环境,由 std::locale::global
设置。
这或多或少意味着编译器无法提前知道将使用哪个语言环境,这意味着将间接调用某个函数将每个字符转换为小写在当前语言环境中。
另一方面,strcasecmp
的 documentation 指出:
In the POSIX locale, strcasecmp() and strncasecmp() shall behave as if the strings had been converted to lowercase and then a byte comparison performed. The results are unspecified in other locales.
这意味着语言环境是固定的,因此您可以预期它会被大量优化。