问题
Suppose, most of the time I have below scenario for replacement:
std::string line; // "line" contains a big string.
std::string from = "abcd";
std::string to = "xy"; // to.length() < from.length()
// replace "from" with "to" everywhere in "line"
Here the string
class has to put "xy"
and then erase 2 characters which effectively shifts all character in line
towards left. There are so many such replacements happening throughout the life of my code.
Now coming to the real question. Below is also acceptable for me:
// ...
if(to.legnth() < from.length())
to.resize(from.length(), ' ');
// now to.length() = from.length()
// replace "from" with "to" everywhere in "line"
Above exercise is helpful only if replace()
is optimized for same length strings. It should be because that's trivial; but just wanted to confirm if someone has the 1st hand knowledge.
I tried browsing through Eclipse IDE into string class, but couldn't dig into so much.
回答1:
I just look at MSVC 2008's implementation. They do optimize (I omit some stuff):
_Myt& __CLR_OR_THIS_CALL replace(size_type _Off,
size_type _N0, const _Myt& _Right, size_type _Roff, size_type _Count)
{
...
if (_Count <= _N0)
{ // hole doesn't get larger, just copy in substring
_Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
_Myptr() + _Roff, _Count); // fill hole
_Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // move tail down
}
else if (_Roff <= _Off)
{ // hole gets larger, substring begins before hole
_Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // move tail down
_Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
_Myptr() + _Roff, _Count); // fill hole
}
else if (_Off + _N0 <= _Roff)
{ // hole gets larger, substring begins after hole
_Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // move tail down
_Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
_Myptr() + (_Roff + _Count - _N0), _Count); // fill hole
}
else
{ // hole gets larger, substring begins in hole
_Traits_helper::move_s<_Traits>(_Myptr() + _Off, _Myres - _Off,
_Myptr() + _Roff, _N0); // fill old hole
_Traits_helper::move_s<_Traits>(_Myptr() + _Off + _Count, _Myres - _Off - _Count,
_Myptr() + _Off + _N0, _Nm); // move tail down
_Traits_helper::move_s<_Traits>(_Myptr() + _Off + _N0, _Myres - _Off - _N0, _Myptr() + _Roff + _Count,
_Count - _N0); // fill rest of new hole
}
...
}
Take an attantion, that the case when new length is smaller and the case when lengths are equal are similar.
Edit: It can be concluded that in the case of same length strings after copying data, total "0" characters/holes have to be moved/filled (i.e. no movement). Thus no optimization is really needed, but it's taken care trivially.
来源:https://stackoverflow.com/questions/14321174/is-stdstringreplace-optimized-for-same-length-strings