У меня есть куча кода, где сравниваются объекты типа 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, скорее всего, неизбежна - здесь есть тысячи строк кода. Выход из строковых литералов и сравнение с == также вероятно неизбежны - переписывание всего кода будет больно.
Проблема в реализации STL, которая поставляется с Visual С++ 11, использует несколько странный подход. == отображается на std::operator==(const basic_string&, const char*), который вызывает basic_string::compare( const char* ), который в свою очередь вызывает std::char_traits<char>( const char* ), который вызывает strlen(), чтобы вычислить длину строкового литерала. Затем выполняется сравнение для двух строк, и в это сравнение передаются длины обеих строк.
Компилятор с трудом анализирует все это и испускает код, который дважды пересекает строковый литерал. С короткими литералами, которые не так много времени, но каждое сравнение предполагает прохождение буквального дважды вместо одного раза. Просто вызов strcmp() скорее всего будет быстрее.
Есть ли что-нибудь, что я мог бы сделать, например, написать собственный класс компаратора, который поможет избежать чередования строковых литералов дважды в этом сценарии?