У меня есть куча кода, где сравниваются объекты типа 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()
скорее всего будет быстрее.
Есть ли что-нибудь, что я мог бы сделать, например, написать собственный класс компаратора, который поможет избежать чередования строковых литералов дважды в этом сценарии?