我有一堆代码,其中类型为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
对象进行比较,而是继续与字符串字面值进行比较? - Dietmar Kühltemplate <size_t N> std::operator(const str&, const char (c&)[N])
- 如果它能够更明确地绑定,那么您可以为0、1、2、3、4的N进行特化,并推迟到现有的比较或者使用memcmp
。您可以使用例如从c_str()
转换为 int16/int32 的 mem 强制转换进行单个比较... - Tony Delroychar const *s = someString.c_str(); if ( !std::strcmp(s, "(")) {
等。 - M.M