From 8a6270322b0767fd7f9956f90538ca55d341fab5 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/trunk@54860 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/string.cpp | 59 ++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/src/common/string.cpp b/src/common/string.cpp index c3bc9331cb..362d682fb2 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -1239,27 +1239,56 @@ size_t wxString::Replace(const wxString& strOld, size_t uiCount = 0; // count of replacements made - const size_t uiOldLen = strOld.m_impl.length(); - const size_t uiNewLen = strNew.m_impl.length(); + // optimize the special common case: replacement of one character by + // another one (in UTF-8 case we can only do this for ASCII characters) + // + // benchmarks show that this special version is around 3 times faster + // (depending on the proportion of matching characters and UTF-8/wchar_t + // build) + if ( strOld.m_impl.length() == 1 && strNew.m_impl.length() == 1 ) + { + const wxStringCharType chOld = strOld.m_impl[0], + chNew = strNew.m_impl[0]; + + // this loop is the simplified version of the one below + for ( size_t pos = 0; ; ) + { + pos = m_impl.find(chOld, pos); + if ( pos == npos ) + break; - for ( size_t dwPos = 0; dwPos < m_impl.length(); ) + m_impl[pos++] = chNew; + + uiCount++; + + if ( !bReplaceAll ) + break; + } + } + else // general case { - dwPos = m_impl.find(strOld.m_impl, dwPos); - if ( dwPos == npos ) - break; + const size_t uiOldLen = strOld.m_impl.length(); + const size_t uiNewLen = strNew.m_impl.length(); + + for ( size_t pos = 0; ; ) + { + pos = m_impl.find(strOld.m_impl, pos); + if ( pos == npos ) + break; - // replace this occurance of the old string with the new one - m_impl.replace(dwPos, uiOldLen, strNew.m_impl); + // replace this occurrence of the old string with the new one + m_impl.replace(pos, uiOldLen, strNew.m_impl); - // move up pos past the string that was replaced - dwPos += uiNewLen; + // move up pos past the string that was replaced + pos += uiNewLen; - // increase replace count - ++uiCount; + // increase replace count + uiCount++; - // stop after the first one? - if ( !bReplaceAll ) - break; + // stop after the first one? + if ( !bReplaceAll ) + break; + } } return uiCount; -- 2.45.2