From f7d2f0f9e712b020b98a8f1ac4ae9c74be07bf88 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 30 Jul 2008 21:41:07 +0000 Subject: [PATCH] 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 --- docs/changes.txt | 1 + src/common/string.cpp | 59 +++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index faea32f319..7b57f30244 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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): diff --git a/src/common/string.cpp b/src/common/string.cpp index c0918eed96..06f7e5298a 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -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; } }