【发布时间】:2014-07-15 08:12:50
【问题描述】:
我有一堆代码,其中将 std::string 类型的对象与字符串文字进行了比较,以确定其是否相等。像这样的:
//const std:string someString = //blahblahblah;
if( someString == "(" ) {
//do something
} else if( someString == ")" ) {
//do something else
} else if// this chain can be very long
比较时间累积到相当多(是的,我分析过),所以加快比较时间会很好。
代码将字符串与许多短字符串文字进行比较,这种比较几乎无法避免。保留声明为std::string 的字符串很可能是不可避免的——这样的代码有数千行。留下字符串文字并与 == 进行比较也可能是不可避免的 - 重写整个代码会很痛苦。
问题在于 Visual C++11 附带的 STL 实现使用了一些奇怪的方法。 == 映射到 std::operator==(const basic_string&, const char*),后者调用 basic_string::compare( const char* ),后者又调用 std::char_traits<char>( const char* ),后者调用 strlen() 来计算字符串文字的长度。然后对两个字符串进行比较,并将两个字符串的长度传递到该比较中。
编译器很难分析所有这些并发出两次遍历字符串文字的代码。使用较短的文字时间不多,但每次比较都涉及遍历文字两次而不是一次。简单地调用strcmp() 很可能会更快。
有什么我可以做的,比如编写一个自定义比较器类来帮助避免在这种情况下两次遍历字符串文字?
【问题讨论】:
-
如果您分析问题出在对
strlen()的调用上,为什么还要继续与字符串文字进行比较,而不是与一组预先构造的std::string const对象进行比较? -
@DietmarKühl:这段代码太多了,我不可能将所有这些文字声明为字符串对象并保持代码可维护。
-
在不修改客户端代码的情况下拦截比较会很棘手......我会尝试添加
template <size_t N> std::operator(const str&, const char (c&)[N])- 如果这恰好可以更好地明确绑定,那么您可以将其专门用于 N 0,1,2,3,4 并遵循现有的比较,或者例如memcmp,否则。您可以使用例如将 mem 从c_str()转换为 int16/int32 进行单一比较.... -
@TonyD:这似乎绑定正确。
-
您可以通过以下方式避免所有关于 char_traits 和意外计算的内容:
char const *s = someString.c_str(); if ( !std::strcmp(s, "(")) {等。
标签: c++ string performance visual-c++ stl