optimize Replace() for the common case of replacing one character with another one (#9802)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@54860 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-07-30 21:41:07 +00:00
parent ef00e5367e
commit f7d2f0f9e7
2 changed files with 38 additions and 22 deletions

View File

@@ -93,6 +93,7 @@ Major new features in 2.8 release
All:
- Optimize wxString::Replace() for single character arguments.
- Updated Hindi translation (Priyank Bolia).
All (GUI):

View File

@@ -1492,8 +1492,8 @@ wxString wxString::AfterFirst(wxChar ch) const
}
// replace first (or all) occurences of some substring with another one
size_t wxString::Replace(const wxChar *szOld,
const wxChar *szNew, bool bReplaceAll)
size_t
wxString::Replace(const wxChar *szOld, const wxChar *szNew, bool bReplaceAll)
{
// if we tried to replace an empty string we'd enter an infinite loop below
wxCHECK_MSG( szOld && *szOld && szNew, 0,
@@ -1501,33 +1501,48 @@ size_t wxString::Replace(const wxChar *szOld,
size_t uiCount = 0; // count of replacements made
size_t uiOldLen = wxStrlen(szOld);
size_t uiNewLen = wxStrlen(szNew);
size_t dwPos = 0;
while ( this->c_str()[dwPos] != wxT('\0') )
// optimize the special common case of replacing one character with another
// one
if ( szOld[1] == '\0' && szNew[1] == '\0' )
{
//DO NOT USE STRSTR HERE
//this string can contain embedded null characters,
//so strstr will function incorrectly
dwPos = find(szOld, dwPos);
if ( dwPos == npos )
break; // exit the loop
else
// this loop is the simplified version of the one below
for ( size_t pos = 0; ; )
{
//replace this occurance of the old string with the new one
replace(dwPos, uiOldLen, szNew, uiNewLen);
pos = find(*szOld, pos);
if ( pos == npos )
break;
//move up pos past the string that was replaced
dwPos += uiNewLen;
(*this)[pos++] = *szNew;
//increase replace count
++uiCount;
uiCount++;
if ( !bReplaceAll )
break;
}
}
else // general case
{
const size_t uiOldLen = wxStrlen(szOld);
const size_t uiNewLen = wxStrlen(szNew);
for ( size_t pos = 0; ; )
{
pos = find(szOld, pos);
if ( pos == npos )
break;
// replace this occurrence of the old string with the new one
replace(pos, uiOldLen, szNew, uiNewLen);
// move past the string that was replaced
pos += uiNewLen;
// increase replace count
uiCount++;
// stop now?
if ( !bReplaceAll )
break; // exit the loop
break;
}
}