To make this more efficient, you have to consider what's inefficient about it. I see two main contenders:
- Data copies
- Data scans
You copy data in up to three places. First when
str is passed into the function it may be copied or it may be moved. Second when you take
trimmed = str.substr(..) you copy a presumably large portion of the string. Third when you take
trimmed = trimmed.substr(..) you do so again. In the worst case (when no whitespace is removed) this is two or three full copies of your string.
You scan data in two places. First when you scan
str forward, looking for non-whitespace. Second when you scan
str forward, looking for whitespace. The latter appears to be a mistake, as you use the index this calculates against
trimmed, and, as Jamal found, strings with leading whitespace result in empty strings being returned. It seems to me that instead of finding the first whitespace character, you need to find the last non-whitespace.
My recommendations are as follows. If run-time efficiency is your ultimate concern (as opposed to programmer efficiency or other concerns), consider changing your function signature to pass a string by reference. This avoids the initial possible copy. Then avoid the other two copies by modifying the passed string in place with
std::string::erase instead of
std::string::substr. If you stick to
std::string::substr, definitely find both ends and only call
substr once. Second, unless you mean something unusual by "leading and trailing whitespace" (such as returning the first whitespace delimited substring) scan for trailing whitespace from the end of your string.
If run-time efficiency is your ultimate concern, you can't optimize properly without knowing more about your data. Do you typically see large amounts of whitespace at one or both ends of your string, or is it typically a relatively small amount? If possible, profile a few approaches against a representative data set. If you typically extract small desired strings from within large amounts of whitespace, it's possible that a passing a
const string& and returning the results of a single call to
std::string::substr(pos, len) will be faster. But if you typically remove no whitespace, it's hard to beat in-place even with C++11's move semantics.