Выполнение функции обрезки - PullRequest
7 голосов
/ 30 ноября 2010

Моя старая функция обрезки:

string TailTrimString (const string & sSource, const char *chars) {
  size_t End = sSource.find_last_not_of(chars);
  if (End == string::npos) {
    // only "*chars"
    return "";
  }
  if (End == sSource.size() - 1) {
    // noting to trim
    return sSource;
  }
  return sSource.substr(0, End + 1);
}

Вместо этого я решил использовать boost и написал тривиальное:

string TailTrimString (const string & sSource, const char *chars) {
    return boost::algorithm::trim_right_copy_if(sSource,boost::algorithm::is_any_of(chars));
}

И я был поражен, узнав, что новая функция работает намного медленнее. Я провел некоторое профилирование и вижу, что функция is_any_of очень медленная.

Возможно ли, что реализация boost работает медленнее, чем моя довольно простая реализация? Что-нибудь, что я должен использовать вместо is_any_of, чтобы улучшить производительность?

Я также нашел обсуждение по этому вопросу в списке рассылки буста, но я все еще не уверен, как можно улучшить производительность моего кода.

Буст-версия, которую я использую, - 1.38, которая довольно старая, но, думаю, с тех пор этот код не сильно изменился.

Спасибо.

Ответы [ 3 ]

4 голосов
/ 30 ноября 2010

Возможно ли, что реализация boost работает медленнее, чем моя довольно простая реализация?

Конечно.

Что-нибудь, что я должен использовать вместо is_any_of для улучшения производительности?

Да - ваш оригинальный код. Вы ничего не сказали о том, что он имеет дефект, или о причине, по которой вы повторно применили его с помощью boost. Если в исходном коде не было дефектов, то не было веской причины бросать исходную реализацию.

Введение Boost в кодовую базу имеет смысл. Это приносит много функциональности, которая может быть полезной. Но выпадение функции с единственной целью использования новой технологии - большая ошибка новичка.

EDIT:

В ответ на ваш комментарий:

Я до сих пор не понимаю, почему производительность boost хуже.

Ручная функция, предназначенная для выполнения одной конкретной работы для одного конкретного приложения, часто оказывается быстрее, чем универсальное решение. Boost - это отличная библиотека универсальных инструментов, которые могут сэкономить много программирования и много дефектов. Но это общее. Вам может понадобиться только обрезать вашу строку определенным образом, но Boost обрабатывает все. Это требует времени.

1 голос
/ 01 декабря 2010

В ответ на ваш вопрос об относительной производительности.

Вы используете boost::algorithm::trim_right_copy_if, который, согласно названию, создает копию входных данных до обрезки.Попробуйте использовать boost::algorithm::trim_right_if, чтобы увидеть, имеет ли это лучшую производительность.Эта функция будет выполнять операцию на месте вместо новой строки.

1 голос
/ 30 ноября 2010

В ответ на ваш вопрос об относительной производительности, std::string::find_last_not_of, обернет подпрограммы строки C (такие как strcspan), и они очень быстрые, однако boost::algorithm::is_any_of использует (вероятно, использовал, я 'd опасность того, что в более поздних версиях это изменилось!) std::set для набора символов, который нужно искать, и выполняет проверку в этом наборе для каждого символа - что не будет так быстро!

РЕДАКТИРОВАТЬ: просто чтобы добавить эхо, ваша функция работает, она не нарушена, она не медленная, поэтому не беспокойтесь об ее изменении ...

...