1 /////////////////////////////////////////////////////////////////////////////
2 // Name: tests/benchmarks/strings.cpp
3 // Purpose: String-related benchmarks
4 // Author: Vadim Zeitlin
6 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 #include "wx/string.h"
14 #include "htmlparser/htmlpars.h"
16 static const char asciistr
[] =
17 "This is just the first line of a very long 7 bit ASCII string"
18 "This is just the second line of a very long 7 bit ASCII string"
19 "This is just the third line of a very long 7 bit ASCII string"
20 "This is just the fourth line of a very long 7 bit ASCII string"
21 "This is just the fifth line of a very long 7 bit ASCII string"
22 "This is just the sixth line of a very long 7 bit ASCII string"
23 "This is just the seventh line of a very long 7 bit ASCII string"
24 "This is just the eighth line of a very long 7 bit ASCII string"
25 "This is just the ninth line of a very long 7 bit ASCII string"
26 "This is just the tenth line of a very long 7 bit ASCII string"
29 static const char utf8str
[] =
30 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 0"
31 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 1"
32 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 2"
33 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 3"
34 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 4"
35 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 5"
36 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 6"
37 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 7"
38 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 8"
39 "\xD0\xA6\xD0\xB5\xD0\xBB\xD0\xBE\xD0\xB5 \xD1\x87\xD0\xB8\xD1\x81\xD0\xBB\xD0\xBE 9"
45 const wxString
& GetTestAsciiString()
47 static wxString testString
;
48 if ( testString
.empty() )
50 long num
= Bench::GetNumericParameter();
54 for ( long n
= 0; n
< num
; n
++ )
55 testString
+= wxString::FromAscii(asciistr
);
61 } // anonymous namespace
63 // this is just a baseline
64 BENCHMARK_FUNC(Strlen
)
66 if ( strlen(utf8str
) != WXSIZEOF(utf8str
) - 1 )
69 if ( strlen(asciistr
) != WXSIZEOF(asciistr
) - 1 )
75 // ----------------------------------------------------------------------------
76 // FromUTF8() benchmarks
77 // ----------------------------------------------------------------------------
79 BENCHMARK_FUNC(FromUTF8
)
81 wxString s
= wxString::FromUTF8(utf8str
);
85 s
= wxString::FromUTF8(asciistr
);
92 BENCHMARK_FUNC(FromUTF8WithNpos
)
94 wxString s
= wxString::FromUTF8(utf8str
, wxString::npos
);
98 s
= wxString::FromUTF8(asciistr
, wxString::npos
);
105 BENCHMARK_FUNC(FromUTF8WithLen
)
107 wxString s
= wxString::FromUTF8(utf8str
, WXSIZEOF(utf8str
));
111 s
= wxString::FromUTF8(asciistr
, WXSIZEOF(asciistr
));
118 // ----------------------------------------------------------------------------
119 // FromUTF8Unchecked() benchmarks
120 // ----------------------------------------------------------------------------
122 BENCHMARK_FUNC(FromUTF8Unchecked
)
124 wxString s
= wxString::FromUTF8Unchecked(utf8str
);
128 s
= wxString::FromUTF8Unchecked(asciistr
);
135 BENCHMARK_FUNC(FromUTF8UncheckedWithNpos
)
137 wxString s
= wxString::FromUTF8Unchecked(utf8str
, wxString::npos
);
141 s
= wxString::FromUTF8Unchecked(asciistr
, wxString::npos
);
148 BENCHMARK_FUNC(FromUTF8UncheckedWithLen
)
150 wxString s
= wxString::FromUTF8Unchecked(utf8str
, WXSIZEOF(utf8str
));
154 s
= wxString::FromUTF8Unchecked(asciistr
, WXSIZEOF(asciistr
));
161 // ----------------------------------------------------------------------------
162 // FromAscii() benchmarks
163 // ----------------------------------------------------------------------------
165 BENCHMARK_FUNC(FromAscii
)
167 wxString s
= wxString::FromAscii(asciistr
);
174 BENCHMARK_FUNC(FromAsciiWithNpos
)
176 wxString s
= wxString::FromAscii(asciistr
);
183 BENCHMARK_FUNC(FromAsciiWithLen
)
185 wxString s
= wxString::FromAscii(asciistr
, WXSIZEOF(asciistr
));
192 // ----------------------------------------------------------------------------
193 // simple string iteration
194 // ----------------------------------------------------------------------------
197 BENCHMARK_FUNC(ForCString
)
199 for ( size_t n
= 0; n
< WXSIZEOF(asciistr
); n
++ )
201 if ( asciistr
[n
] == '~' )
208 BENCHMARK_FUNC(ForStringIndex
)
210 const wxString
& s
= GetTestAsciiString();
211 const size_t len
= s
.length();
212 for ( size_t n
= 0; n
< len
; n
++ )
221 BENCHMARK_FUNC(ForStringIter
)
223 const wxString
& s
= GetTestAsciiString();
224 const wxString::const_iterator end
= s
.end();
225 for ( wxString::const_iterator i
= s
.begin(); i
!= end
; ++i
)
234 BENCHMARK_FUNC(ForStringRIter
)
236 const wxString
& s
= GetTestAsciiString();
237 const wxString::const_reverse_iterator rend
= s
.rend();
238 for ( wxString::const_reverse_iterator i
= s
.rbegin(); i
!= rend
; ++i
)
247 // ----------------------------------------------------------------------------
248 // wxString::Replace()
249 // ----------------------------------------------------------------------------
251 const size_t ASCIISTR_LEN
= strlen(asciistr
);
253 BENCHMARK_FUNC(ReplaceLoop
)
255 wxString
str('x', ASCIISTR_LEN
);
256 for ( size_t n
= 0; n
< ASCIISTR_LEN
; n
++ )
262 return str
.length() != 0;
265 BENCHMARK_FUNC(ReplaceNone
)
267 wxString
str('x', ASCIISTR_LEN
);
268 return str
.Replace("a", "z") == 0;
271 BENCHMARK_FUNC(ReplaceSome
)
273 wxString
str(asciistr
);
274 return str
.Replace("7", "8") != 0;
277 BENCHMARK_FUNC(ReplaceAll
)
279 wxString
str('x', ASCIISTR_LEN
);
280 return str
.Replace("x", "y") != 0;
283 BENCHMARK_FUNC(ReplaceLonger
)
285 wxString
str('x', ASCIISTR_LEN
);
286 return str
.Replace("x", "yy") != 0;
289 BENCHMARK_FUNC(ReplaceShorter
)
291 wxString
str('x', ASCIISTR_LEN
);
292 return str
.Replace("xx", "y") != 0;
295 // ----------------------------------------------------------------------------
296 // string case conversion
297 // ----------------------------------------------------------------------------
299 BENCHMARK_FUNC(Lower
)
301 return GetTestAsciiString().Lower().length() > 0;
304 BENCHMARK_FUNC(Upper
)
306 return GetTestAsciiString().Upper().length() > 0;
309 // ----------------------------------------------------------------------------
311 // ----------------------------------------------------------------------------
313 BENCHMARK_FUNC(StrcmpA
)
315 const wxString
& s
= GetTestAsciiString();
317 return wxCRT_StrcmpA(s
.c_str(), s
.c_str()) == 0;
320 BENCHMARK_FUNC(StrcmpW
)
322 const wxString
& s
= GetTestAsciiString();
324 return wxCRT_StrcmpW(s
.wc_str(), s
.wc_str()) == 0;
327 BENCHMARK_FUNC(StricmpA
)
329 const wxString
& s
= GetTestAsciiString();
331 return wxCRT_StricmpA(s
.c_str(), s
.c_str()) == 0;
334 BENCHMARK_FUNC(StricmpW
)
336 const wxString
& s
= GetTestAsciiString();
338 return wxCRT_StricmpW(s
.wc_str(), s
.wc_str()) == 0;
341 BENCHMARK_FUNC(StringCmp
)
343 const wxString
& s
= GetTestAsciiString();
345 return s
.Cmp(s
) == 0;
348 BENCHMARK_FUNC(StringCmpNoCase
)
350 const wxString
& s
= GetTestAsciiString();
352 return s
.CmpNoCase(s
) == 0;
355 // Also benchmark various native functions under MSW. Surprisingly/annoyingly
356 // they sometimes have vastly better performance than alternatives, especially
357 // for case-sensitive comparison (see #10375).
360 #include "wx/msw/wrapwin.h"
362 BENCHMARK_FUNC(MSWlstrcmp
)
364 const wxString
& s
= GetTestAsciiString();
366 return lstrcmp(s
.t_str(), s
.t_str()) == 0;
369 BENCHMARK_FUNC(MSWlstrcmpi
)
371 const wxString
& s
= GetTestAsciiString();
373 return lstrcmpi(s
.t_str(), s
.t_str()) == 0;
376 BENCHMARK_FUNC(MSWCompareString
)
378 const wxString
& s
= GetTestAsciiString();
380 return ::CompareString
384 s
.t_str(), s
.length(),
385 s
.t_str(), s
.length()
389 BENCHMARK_FUNC(MSWCompareStringIgnoreCase
)
391 const wxString
& s
= GetTestAsciiString();
393 return ::CompareString
397 s
.t_str(), s
.length(),
398 s
.t_str(), s
.length()
402 #endif // __WINDOWS__
404 // ----------------------------------------------------------------------------
405 // string buffers: wx[W]CharBuffer
406 // ----------------------------------------------------------------------------
408 BENCHMARK_FUNC(CharBuffer
)
410 wxString
str(asciistr
);
412 // NB: wxStrlen() is here to simulate some use of the returned buffer.
413 // Both mb_str() and wc_str() are used so that this code does something
414 // nontrivial in any build.
415 return wxStrlen(str
.mb_str()) == ASCIISTR_LEN
&&
416 wxStrlen(str
.wc_str()) == ASCIISTR_LEN
;
420 // ----------------------------------------------------------------------------
421 // wxString::operator[] - parse large HTML page
422 // ----------------------------------------------------------------------------
424 class DummyParser
: public wx28HtmlParser
427 virtual wxObject
* GetProduct() { return NULL
; }
428 virtual void AddText(const wxChar
*) {}
432 BENCHMARK_FUNC(ParseHTML
)
434 // static so that construction time is not counted
435 static DummyParser parser
;
436 static wxString html
;
440 wxFFile("htmltest.html").ReadAll(&html1
, wxConvUTF8
);
442 // this is going to make for some invalid HTML, of course, but it
443 // doesn't really matter
444 long num
= Bench::GetNumericParameter();
448 for ( long n
= 0; n
< num
; n
++ )