1 /////////////////////////////////////////////////////////////////////////////
2 // Name: tests/benchmarks/strings.cpp
3 // Purpose: String-related benchmarks
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #include "wx/string.h"
15 #include "htmlparser/htmlpars.h"
17 static const char asciistr
[] =
18 "This is just the first line of a very long 7 bit ASCII string"
19 "This is just the second line of a very long 7 bit ASCII string"
20 "This is just the third line of a very long 7 bit ASCII string"
21 "This is just the fourth line of a very long 7 bit ASCII string"
22 "This is just the fifth line of a very long 7 bit ASCII string"
23 "This is just the sixth line of a very long 7 bit ASCII string"
24 "This is just the seventh line of a very long 7 bit ASCII string"
25 "This is just the eighth line of a very long 7 bit ASCII string"
26 "This is just the ninth line of a very long 7 bit ASCII string"
27 "This is just the tenth line of a very long 7 bit ASCII string"
30 static const char utf8str
[] =
31 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 0"
32 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 1"
33 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 2"
34 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 3"
35 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 4"
36 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 5"
37 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 6"
38 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 7"
39 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 8"
40 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 9"
46 const wxString
& GetTestAsciiString()
48 static wxString testString
;
49 if ( testString
.empty() )
51 long num
= Bench::GetNumericParameter();
55 for ( long n
= 0; n
< num
; n
++ )
56 testString
+= wxString::FromAscii(asciistr
);
62 } // anonymous namespace
64 // this is just a baseline
65 BENCHMARK_FUNC(Strlen
)
67 if ( strlen(utf8str
) != WXSIZEOF(utf8str
) - 1 )
70 if ( strlen(asciistr
) != WXSIZEOF(asciistr
) - 1 )
76 // ----------------------------------------------------------------------------
77 // FromUTF8() benchmarks
78 // ----------------------------------------------------------------------------
80 BENCHMARK_FUNC(FromUTF8
)
82 wxString s
= wxString::FromUTF8(utf8str
);
86 s
= wxString::FromUTF8(asciistr
);
93 BENCHMARK_FUNC(FromUTF8WithNpos
)
95 wxString s
= wxString::FromUTF8(utf8str
, wxString::npos
);
99 s
= wxString::FromUTF8(asciistr
, wxString::npos
);
106 BENCHMARK_FUNC(FromUTF8WithLen
)
108 wxString s
= wxString::FromUTF8(utf8str
, WXSIZEOF(utf8str
));
112 s
= wxString::FromUTF8(asciistr
, WXSIZEOF(asciistr
));
119 // ----------------------------------------------------------------------------
120 // FromUTF8Unchecked() benchmarks
121 // ----------------------------------------------------------------------------
123 BENCHMARK_FUNC(FromUTF8Unchecked
)
125 wxString s
= wxString::FromUTF8Unchecked(utf8str
);
129 s
= wxString::FromUTF8Unchecked(asciistr
);
136 BENCHMARK_FUNC(FromUTF8UncheckedWithNpos
)
138 wxString s
= wxString::FromUTF8Unchecked(utf8str
, wxString::npos
);
142 s
= wxString::FromUTF8Unchecked(asciistr
, wxString::npos
);
149 BENCHMARK_FUNC(FromUTF8UncheckedWithLen
)
151 wxString s
= wxString::FromUTF8Unchecked(utf8str
, WXSIZEOF(utf8str
));
155 s
= wxString::FromUTF8Unchecked(asciistr
, WXSIZEOF(asciistr
));
162 // ----------------------------------------------------------------------------
163 // FromAscii() benchmarks
164 // ----------------------------------------------------------------------------
166 BENCHMARK_FUNC(FromAscii
)
168 wxString s
= wxString::FromAscii(asciistr
);
175 BENCHMARK_FUNC(FromAsciiWithNpos
)
177 wxString s
= wxString::FromAscii(asciistr
);
184 BENCHMARK_FUNC(FromAsciiWithLen
)
186 wxString s
= wxString::FromAscii(asciistr
, WXSIZEOF(asciistr
));
193 // ----------------------------------------------------------------------------
194 // simple string iteration
195 // ----------------------------------------------------------------------------
198 BENCHMARK_FUNC(ForCString
)
200 for ( size_t n
= 0; n
< WXSIZEOF(asciistr
); n
++ )
202 if ( asciistr
[n
] == '~' )
209 BENCHMARK_FUNC(ForStringIndex
)
211 const wxString
& s
= GetTestAsciiString();
212 const size_t len
= s
.length();
213 for ( size_t n
= 0; n
< len
; n
++ )
222 BENCHMARK_FUNC(ForStringIter
)
224 const wxString
& s
= GetTestAsciiString();
225 const wxString::const_iterator end
= s
.end();
226 for ( wxString::const_iterator i
= s
.begin(); i
!= end
; ++i
)
235 BENCHMARK_FUNC(ForStringRIter
)
237 const wxString
& s
= GetTestAsciiString();
238 const wxString::const_reverse_iterator rend
= s
.rend();
239 for ( wxString::const_reverse_iterator i
= s
.rbegin(); i
!= rend
; ++i
)
248 // ----------------------------------------------------------------------------
249 // wxString::Replace()
250 // ----------------------------------------------------------------------------
252 const size_t ASCIISTR_LEN
= strlen(asciistr
);
254 BENCHMARK_FUNC(ReplaceLoop
)
256 wxString
str('x', ASCIISTR_LEN
);
257 for ( size_t n
= 0; n
< ASCIISTR_LEN
; n
++ )
263 return str
.length() != 0;
266 BENCHMARK_FUNC(ReplaceNone
)
268 wxString
str('x', ASCIISTR_LEN
);
269 return str
.Replace("a", "z") == 0;
272 BENCHMARK_FUNC(ReplaceSome
)
274 wxString
str(asciistr
);
275 return str
.Replace("7", "8") != 0;
278 BENCHMARK_FUNC(ReplaceAll
)
280 wxString
str('x', ASCIISTR_LEN
);
281 return str
.Replace("x", "y") != 0;
284 BENCHMARK_FUNC(ReplaceLonger
)
286 wxString
str('x', ASCIISTR_LEN
);
287 return str
.Replace("x", "yy") != 0;
290 BENCHMARK_FUNC(ReplaceShorter
)
292 wxString
str('x', ASCIISTR_LEN
);
293 return str
.Replace("xx", "y") != 0;
296 // ----------------------------------------------------------------------------
297 // string case conversion
298 // ----------------------------------------------------------------------------
300 BENCHMARK_FUNC(Lower
)
302 return GetTestAsciiString().Lower().length() > 0;
305 BENCHMARK_FUNC(Upper
)
307 return GetTestAsciiString().Upper().length() > 0;
310 // ----------------------------------------------------------------------------
312 // ----------------------------------------------------------------------------
314 BENCHMARK_FUNC(StrcmpA
)
316 const wxString
& s
= GetTestAsciiString();
318 return wxCRT_StrcmpA(s
.c_str(), s
.c_str()) == 0;
321 BENCHMARK_FUNC(StrcmpW
)
323 const wxString
& s
= GetTestAsciiString();
325 return wxCRT_StrcmpW(s
.wc_str(), s
.wc_str()) == 0;
328 BENCHMARK_FUNC(StricmpA
)
330 const wxString
& s
= GetTestAsciiString();
332 return wxCRT_StricmpA(s
.c_str(), s
.c_str()) == 0;
335 BENCHMARK_FUNC(StricmpW
)
337 const wxString
& s
= GetTestAsciiString();
339 return wxCRT_StricmpW(s
.wc_str(), s
.wc_str()) == 0;
342 BENCHMARK_FUNC(StringCmp
)
344 const wxString
& s
= GetTestAsciiString();
346 return s
.Cmp(s
) == 0;
349 BENCHMARK_FUNC(StringCmpNoCase
)
351 const wxString
& s
= GetTestAsciiString();
353 return s
.CmpNoCase(s
) == 0;
356 // Also benchmark various native functions under MSW. Surprisingly/annoyingly
357 // they sometimes have vastly better performance than alternatives, especially
358 // for case-sensitive comparison (see #10375).
361 #include "wx/msw/wrapwin.h"
363 BENCHMARK_FUNC(MSWlstrcmp
)
365 const wxString
& s
= GetTestAsciiString();
367 return lstrcmp(s
.t_str(), s
.t_str()) == 0;
370 BENCHMARK_FUNC(MSWlstrcmpi
)
372 const wxString
& s
= GetTestAsciiString();
374 return lstrcmpi(s
.t_str(), s
.t_str()) == 0;
377 BENCHMARK_FUNC(MSWCompareString
)
379 const wxString
& s
= GetTestAsciiString();
381 return ::CompareString
385 s
.t_str(), s
.length(),
386 s
.t_str(), s
.length()
390 BENCHMARK_FUNC(MSWCompareStringIgnoreCase
)
392 const wxString
& s
= GetTestAsciiString();
394 return ::CompareString
398 s
.t_str(), s
.length(),
399 s
.t_str(), s
.length()
403 #endif // __WINDOWS__
405 // ----------------------------------------------------------------------------
406 // string buffers: wx[W]CharBuffer
407 // ----------------------------------------------------------------------------
409 BENCHMARK_FUNC(CharBuffer
)
411 wxString
str(asciistr
);
413 // NB: wxStrlen() is here to simulate some use of the returned buffer.
414 // Both mb_str() and wc_str() are used so that this code does something
415 // nontrivial in any build.
416 return wxStrlen(str
.mb_str()) == ASCIISTR_LEN
&&
417 wxStrlen(str
.wc_str()) == ASCIISTR_LEN
;
421 // ----------------------------------------------------------------------------
422 // wxString::operator[] - parse large HTML page
423 // ----------------------------------------------------------------------------
425 class DummyParser
: public wx28HtmlParser
428 virtual wxObject
* GetProduct() { return NULL
; }
429 virtual void AddText(const wxChar
*) {}
433 BENCHMARK_FUNC(ParseHTML
)
435 // static so that construction time is not counted
436 static DummyParser parser
;
437 static wxString html
;
441 wxFFile("htmltest.html").ReadAll(&html1
, wxConvUTF8
);
443 // this is going to make for some invalid HTML, of course, but it
444 // doesn't really matter
445 long num
= Bench::GetNumericParameter();
449 for ( long n
= 0; n
< num
; n
++ )