+// ----------------------------------------------------------------------------
+// wxString::Replace()
+// ----------------------------------------------------------------------------
+
+const size_t ASCIISTR_LEN = strlen(asciistr);
+
+BENCHMARK_FUNC(ReplaceLoop)
+{
+ wxString str('x', ASCIISTR_LEN);
+ for ( size_t n = 0; n < ASCIISTR_LEN; n++ )
+ {
+ if ( str[n] == 'a' )
+ str[n] = 'z';
+ }
+
+ return str.length() != 0;
+}
+
+BENCHMARK_FUNC(ReplaceNone)
+{
+ wxString str('x', ASCIISTR_LEN);
+ return str.Replace("a", "z") == 0;
+}
+
+BENCHMARK_FUNC(ReplaceSome)
+{
+ wxString str(asciistr);
+ return str.Replace("7", "8") != 0;
+}
+
+BENCHMARK_FUNC(ReplaceAll)
+{
+ wxString str('x', ASCIISTR_LEN);
+ return str.Replace("x", "y") != 0;
+}
+
+BENCHMARK_FUNC(ReplaceLonger)
+{
+ wxString str('x', ASCIISTR_LEN);
+ return str.Replace("x", "yy") != 0;
+}
+
+BENCHMARK_FUNC(ReplaceShorter)
+{
+ wxString str('x', ASCIISTR_LEN);
+ return str.Replace("xx", "y") != 0;
+}
+
+// ----------------------------------------------------------------------------
+// string case conversion
+// ----------------------------------------------------------------------------
+
+BENCHMARK_FUNC(Lower)
+{
+ return GetTestAsciiString().Lower().length() > 0;
+}
+
+BENCHMARK_FUNC(Upper)
+{
+ return GetTestAsciiString().Upper().length() > 0;
+}
+
+// ----------------------------------------------------------------------------
+// string comparison
+// ----------------------------------------------------------------------------
+
+BENCHMARK_FUNC(StrcmpA)
+{
+ const wxString& s = GetTestAsciiString();
+
+ return wxCRT_StrcmpA(s.c_str(), s.c_str()) == 0;
+}
+
+BENCHMARK_FUNC(StrcmpW)
+{
+ const wxString& s = GetTestAsciiString();
+
+ return wxCRT_StrcmpW(s.wc_str(), s.wc_str()) == 0;
+}
+
+BENCHMARK_FUNC(StricmpA)
+{
+ const wxString& s = GetTestAsciiString();
+
+ return wxCRT_StricmpA(s.c_str(), s.c_str()) == 0;
+}
+
+BENCHMARK_FUNC(StricmpW)
+{
+ const wxString& s = GetTestAsciiString();
+
+ return wxCRT_StricmpW(s.wc_str(), s.wc_str()) == 0;
+}
+
+BENCHMARK_FUNC(StringCmp)
+{
+ const wxString& s = GetTestAsciiString();
+
+ return s.Cmp(s) == 0;
+}
+
+BENCHMARK_FUNC(StringCmpNoCase)
+{
+ const wxString& s = GetTestAsciiString();
+
+ return s.CmpNoCase(s) == 0;
+}
+
+// Also benchmark various native functions under MSW. Surprisingly/annoyingly
+// they sometimes have vastly better performance than alternatives, especially
+// for case-sensitive comparison (see #10375).
+#ifdef __WINDOWS__
+
+#include "wx/msw/wrapwin.h"
+
+BENCHMARK_FUNC(MSWlstrcmp)
+{
+ const wxString& s = GetTestAsciiString();
+
+ return lstrcmp(s.t_str(), s.t_str()) == 0;
+}
+
+BENCHMARK_FUNC(MSWlstrcmpi)
+{
+ const wxString& s = GetTestAsciiString();
+
+ return lstrcmpi(s.t_str(), s.t_str()) == 0;
+}
+
+BENCHMARK_FUNC(MSWCompareString)
+{
+ const wxString& s = GetTestAsciiString();
+
+ return ::CompareString
+ (
+ LOCALE_USER_DEFAULT,
+ 0,
+ s.t_str(), s.length(),
+ s.t_str(), s.length()
+ ) == CSTR_EQUAL;
+}
+
+BENCHMARK_FUNC(MSWCompareStringIgnoreCase)
+{
+ const wxString& s = GetTestAsciiString();
+
+ return ::CompareString
+ (
+ LOCALE_USER_DEFAULT,
+ NORM_IGNORECASE,
+ s.t_str(), s.length(),
+ s.t_str(), s.length()
+ ) == CSTR_EQUAL;
+}
+
+#endif // __WINDOWS__
+
+// ----------------------------------------------------------------------------
+// string buffers: wx[W]CharBuffer
+// ----------------------------------------------------------------------------
+
+BENCHMARK_FUNC(CharBuffer)
+{
+ wxString str(asciistr);
+
+ // NB: wxStrlen() is here to simulate some use of the returned buffer.
+ // Both mb_str() and wc_str() are used so that this code does something
+ // nontrivial in any build.
+ return wxStrlen(str.mb_str()) == ASCIISTR_LEN &&
+ wxStrlen(str.wc_str()) == ASCIISTR_LEN;
+}
+
+
+// ----------------------------------------------------------------------------
+// wxString::operator[] - parse large HTML page
+// ----------------------------------------------------------------------------
+
+class DummyParser : public wx28HtmlParser
+{
+public:
+ virtual wxObject* GetProduct() { return NULL; }
+ virtual void AddText(const wxChar*) {}
+};
+
+
+BENCHMARK_FUNC(ParseHTML)
+{
+ // static so that construction time is not counted
+ static DummyParser parser;
+ static wxString html;
+ if ( html.empty() )
+ {
+ wxString html1;
+ wxFFile("htmltest.html").ReadAll(&html1, wxConvUTF8);
+
+ // this is going to make for some invalid HTML, of course, but it
+ // doesn't really matter
+ long num = Bench::GetNumericParameter();
+ if ( !num )
+ num = 1;
+
+ for ( long n = 0; n < num; n++ )
+ html += html1;
+ }
+
+ parser.Parse(html);
+
+ return true;
+}