]> git.saurik.com Git - wxWidgets.git/blame - tests/benchmarks/strings.cpp
Fix horizontal mouse wheel scrolling in wxGTK.
[wxWidgets.git] / tests / benchmarks / strings.cpp
CommitLineData
dc2ae355
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: tests/benchmarks/strings.cpp
3// Purpose: String-related benchmarks
4// Author: Vadim Zeitlin
5// Created: 2008-07-19
dc2ae355 6// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
526954c5 7// Licence: wxWindows licence
dc2ae355
VZ
8/////////////////////////////////////////////////////////////////////////////
9
10#include "wx/string.h"
c21faa0a 11#include "wx/ffile.h"
dc2ae355
VZ
12
13#include "bench.h"
c21faa0a 14#include "htmlparser/htmlpars.h"
dc2ae355
VZ
15
16static 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"
27 ;
28
29static 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"
40 ;
41
33ccf3d1
VZ
42namespace
43{
44
45const wxString& GetTestAsciiString()
46{
47 static wxString testString;
48 if ( testString.empty() )
49 {
ebfa7cea
VZ
50 long num = Bench::GetNumericParameter();
51 if ( !num )
52 num = 1;
53
54 for ( long n = 0; n < num; n++ )
33ccf3d1
VZ
55 testString += wxString::FromAscii(asciistr);
56 }
57
58 return testString;
59}
60
61} // anonymous namespace
62
dc2ae355
VZ
63// this is just a baseline
64BENCHMARK_FUNC(Strlen)
65{
66 if ( strlen(utf8str) != WXSIZEOF(utf8str) - 1 )
67 return false;
68
69 if ( strlen(asciistr) != WXSIZEOF(asciistr) - 1 )
70 return false;
71
72 return true;
73}
74
75// ----------------------------------------------------------------------------
76// FromUTF8() benchmarks
77// ----------------------------------------------------------------------------
78
79BENCHMARK_FUNC(FromUTF8)
80{
81 wxString s = wxString::FromUTF8(utf8str);
82 if ( s.empty() )
83 return false;
84
85 s = wxString::FromUTF8(asciistr);
86 if ( s.empty() )
87 return false;
88
89 return true;
90}
91
92BENCHMARK_FUNC(FromUTF8WithNpos)
93{
94 wxString s = wxString::FromUTF8(utf8str, wxString::npos);
95 if ( s.empty() )
96 return false;
97
98 s = wxString::FromUTF8(asciistr, wxString::npos);
99 if ( s.empty() )
100 return false;
101
102 return true;
103}
104
105BENCHMARK_FUNC(FromUTF8WithLen)
106{
107 wxString s = wxString::FromUTF8(utf8str, WXSIZEOF(utf8str));
108 if ( s.empty() )
109 return false;
110
111 s = wxString::FromUTF8(asciistr, WXSIZEOF(asciistr));
112 if ( s.empty() )
113 return false;
114
115 return true;
116}
117
118// ----------------------------------------------------------------------------
119// FromUTF8Unchecked() benchmarks
120// ----------------------------------------------------------------------------
121
122BENCHMARK_FUNC(FromUTF8Unchecked)
123{
124 wxString s = wxString::FromUTF8Unchecked(utf8str);
125 if ( s.empty() )
126 return false;
127
128 s = wxString::FromUTF8Unchecked(asciistr);
129 if ( s.empty() )
130 return false;
131
132 return true;
133}
134
135BENCHMARK_FUNC(FromUTF8UncheckedWithNpos)
136{
137 wxString s = wxString::FromUTF8Unchecked(utf8str, wxString::npos);
138 if ( s.empty() )
139 return false;
140
141 s = wxString::FromUTF8Unchecked(asciistr, wxString::npos);
142 if ( s.empty() )
143 return false;
144
145 return true;
146}
147
148BENCHMARK_FUNC(FromUTF8UncheckedWithLen)
149{
150 wxString s = wxString::FromUTF8Unchecked(utf8str, WXSIZEOF(utf8str));
151 if ( s.empty() )
152 return false;
153
154 s = wxString::FromUTF8Unchecked(asciistr, WXSIZEOF(asciistr));
155 if ( s.empty() )
156 return false;
157
158 return true;
159}
160
161// ----------------------------------------------------------------------------
162// FromAscii() benchmarks
163// ----------------------------------------------------------------------------
164
165BENCHMARK_FUNC(FromAscii)
166{
167 wxString s = wxString::FromAscii(asciistr);
168 if ( s.empty() )
169 return false;
170
171 return true;
172}
173
174BENCHMARK_FUNC(FromAsciiWithNpos)
175{
176 wxString s = wxString::FromAscii(asciistr);
177 if ( s.empty() )
178 return false;
179
180 return true;
181}
182
183BENCHMARK_FUNC(FromAsciiWithLen)
184{
185 wxString s = wxString::FromAscii(asciistr, WXSIZEOF(asciistr));
186 if ( s.empty() )
187 return false;
188
189 return true;
190}
191
192// ----------------------------------------------------------------------------
193// simple string iteration
194// ----------------------------------------------------------------------------
195
196// baseline
197BENCHMARK_FUNC(ForCString)
198{
199 for ( size_t n = 0; n < WXSIZEOF(asciistr); n++ )
200 {
201 if ( asciistr[n] == '~' )
202 return false;
203 }
204
205 return true;
206}
207
208BENCHMARK_FUNC(ForStringIndex)
209{
33ccf3d1 210 const wxString& s = GetTestAsciiString();
dc2ae355
VZ
211 const size_t len = s.length();
212 for ( size_t n = 0; n < len; n++ )
213 {
214 if ( s[n] == '~' )
215 return false;
216 }
217
218 return true;
219}
220
221BENCHMARK_FUNC(ForStringIter)
222{
33ccf3d1 223 const wxString& s = GetTestAsciiString();
dc2ae355
VZ
224 const wxString::const_iterator end = s.end();
225 for ( wxString::const_iterator i = s.begin(); i != end; ++i )
226 {
227 if ( *i == '~' )
228 return false;
229 }
230
231 return true;
232}
233
234BENCHMARK_FUNC(ForStringRIter)
235{
33ccf3d1 236 const wxString& s = GetTestAsciiString();
dc2ae355
VZ
237 const wxString::const_reverse_iterator rend = s.rend();
238 for ( wxString::const_reverse_iterator i = s.rbegin(); i != rend; ++i )
239 {
240 if ( *i == '~' )
241 return false;
242 }
243
244 return true;
245}
246
9729777e
VZ
247// ----------------------------------------------------------------------------
248// wxString::Replace()
249// ----------------------------------------------------------------------------
250
0654c03a 251const size_t ASCIISTR_LEN = strlen(asciistr);
9729777e
VZ
252
253BENCHMARK_FUNC(ReplaceLoop)
254{
0654c03a
VS
255 wxString str('x', ASCIISTR_LEN);
256 for ( size_t n = 0; n < ASCIISTR_LEN; n++ )
9729777e
VZ
257 {
258 if ( str[n] == 'a' )
259 str[n] = 'z';
260 }
261
262 return str.length() != 0;
263}
264
543cf9ba 265BENCHMARK_FUNC(ReplaceNone)
9729777e 266{
0654c03a 267 wxString str('x', ASCIISTR_LEN);
543cf9ba
VZ
268 return str.Replace("a", "z") == 0;
269}
9729777e 270
543cf9ba
VZ
271BENCHMARK_FUNC(ReplaceSome)
272{
273 wxString str(asciistr);
274 return str.Replace("7", "8") != 0;
9729777e
VZ
275}
276
543cf9ba 277BENCHMARK_FUNC(ReplaceAll)
9729777e 278{
0654c03a 279 wxString str('x', ASCIISTR_LEN);
543cf9ba 280 return str.Replace("x", "y") != 0;
9729777e
VZ
281}
282
072682ce
VZ
283BENCHMARK_FUNC(ReplaceLonger)
284{
285 wxString str('x', ASCIISTR_LEN);
286 return str.Replace("x", "yy") != 0;
287}
288
289BENCHMARK_FUNC(ReplaceShorter)
290{
291 wxString str('x', ASCIISTR_LEN);
292 return str.Replace("xx", "y") != 0;
293}
294
05f68f2f
VZ
295// ----------------------------------------------------------------------------
296// string case conversion
297// ----------------------------------------------------------------------------
298
299BENCHMARK_FUNC(Lower)
300{
301 return GetTestAsciiString().Lower().length() > 0;
302}
303
304BENCHMARK_FUNC(Upper)
305{
306 return GetTestAsciiString().Upper().length() > 0;
307}
308
309// ----------------------------------------------------------------------------
310// string comparison
311// ----------------------------------------------------------------------------
312
313BENCHMARK_FUNC(StrcmpA)
314{
315 const wxString& s = GetTestAsciiString();
316
7e3ea54f 317 return wxCRT_StrcmpA(s.c_str(), s.c_str()) == 0;
05f68f2f
VZ
318}
319
320BENCHMARK_FUNC(StrcmpW)
321{
322 const wxString& s = GetTestAsciiString();
323
7e3ea54f 324 return wxCRT_StrcmpW(s.wc_str(), s.wc_str()) == 0;
05f68f2f
VZ
325}
326
327BENCHMARK_FUNC(StricmpA)
328{
329 const wxString& s = GetTestAsciiString();
330
7e3ea54f 331 return wxCRT_StricmpA(s.c_str(), s.c_str()) == 0;
05f68f2f
VZ
332}
333
334BENCHMARK_FUNC(StricmpW)
335{
336 const wxString& s = GetTestAsciiString();
337
7e3ea54f 338 return wxCRT_StricmpW(s.wc_str(), s.wc_str()) == 0;
05f68f2f
VZ
339}
340
341BENCHMARK_FUNC(StringCmp)
342{
343 const wxString& s = GetTestAsciiString();
344
345 return s.Cmp(s) == 0;
346}
347
348BENCHMARK_FUNC(StringCmpNoCase)
349{
350 const wxString& s = GetTestAsciiString();
351
352 return s.CmpNoCase(s) == 0;
353}
354
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).
bb5a9514 358#ifdef __WINDOWS__
05f68f2f
VZ
359
360#include "wx/msw/wrapwin.h"
361
362BENCHMARK_FUNC(MSWlstrcmp)
363{
364 const wxString& s = GetTestAsciiString();
365
366 return lstrcmp(s.t_str(), s.t_str()) == 0;
367}
368
369BENCHMARK_FUNC(MSWlstrcmpi)
370{
371 const wxString& s = GetTestAsciiString();
372
373 return lstrcmpi(s.t_str(), s.t_str()) == 0;
374}
375
376BENCHMARK_FUNC(MSWCompareString)
377{
378 const wxString& s = GetTestAsciiString();
379
380 return ::CompareString
381 (
382 LOCALE_USER_DEFAULT,
383 0,
384 s.t_str(), s.length(),
385 s.t_str(), s.length()
386 ) == CSTR_EQUAL;
387}
388
389BENCHMARK_FUNC(MSWCompareStringIgnoreCase)
390{
391 const wxString& s = GetTestAsciiString();
392
393 return ::CompareString
394 (
395 LOCALE_USER_DEFAULT,
396 NORM_IGNORECASE,
397 s.t_str(), s.length(),
398 s.t_str(), s.length()
399 ) == CSTR_EQUAL;
400}
401
bb5a9514 402#endif // __WINDOWS__
0654c03a
VS
403
404// ----------------------------------------------------------------------------
405// string buffers: wx[W]CharBuffer
406// ----------------------------------------------------------------------------
407
408BENCHMARK_FUNC(CharBuffer)
409{
410 wxString str(asciistr);
411
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;
417}
c21faa0a
VS
418
419
420// ----------------------------------------------------------------------------
421// wxString::operator[] - parse large HTML page
422// ----------------------------------------------------------------------------
423
424class DummyParser : public wx28HtmlParser
425{
426public:
427 virtual wxObject* GetProduct() { return NULL; }
428 virtual void AddText(const wxChar*) {}
429};
430
431
432BENCHMARK_FUNC(ParseHTML)
433{
434 // static so that construction time is not counted
435 static DummyParser parser;
436 static wxString html;
437 if ( html.empty() )
438 {
8fad8b2e
VZ
439 wxString html1;
440 wxFFile("htmltest.html").ReadAll(&html1, wxConvUTF8);
441
442 // this is going to make for some invalid HTML, of course, but it
443 // doesn't really matter
ebfa7cea
VZ
444 long num = Bench::GetNumericParameter();
445 if ( !num )
446 num = 1;
447
448 for ( long n = 0; n < num; n++ )
8fad8b2e 449 html += html1;
c21faa0a
VS
450 }
451
452 parser.Parse(html);
453
454 return true;
455}