add the possibility to pass numeric parameters to benchmark functions
[wxWidgets.git] / tests / benchmarks / strings.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: tests/benchmarks/strings.cpp
3 // Purpose: String-related benchmarks
4 // Author: Vadim Zeitlin
5 // Created: 2008-07-19
6 // RCS-ID: $Id$
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows license
9 /////////////////////////////////////////////////////////////////////////////
10
11 #include "wx/string.h"
12 #include "wx/ffile.h"
13
14 #include "bench.h"
15 #include "htmlparser/htmlpars.h"
16
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"
28 ;
29
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"
41 ;
42
43 // this is just a baseline
44 BENCHMARK_FUNC(Strlen)
45 {
46 if ( strlen(utf8str) != WXSIZEOF(utf8str) - 1 )
47 return false;
48
49 if ( strlen(asciistr) != WXSIZEOF(asciistr) - 1 )
50 return false;
51
52 return true;
53 }
54
55 // ----------------------------------------------------------------------------
56 // FromUTF8() benchmarks
57 // ----------------------------------------------------------------------------
58
59 BENCHMARK_FUNC(FromUTF8)
60 {
61 wxString s = wxString::FromUTF8(utf8str);
62 if ( s.empty() )
63 return false;
64
65 s = wxString::FromUTF8(asciistr);
66 if ( s.empty() )
67 return false;
68
69 return true;
70 }
71
72 BENCHMARK_FUNC(FromUTF8WithNpos)
73 {
74 wxString s = wxString::FromUTF8(utf8str, wxString::npos);
75 if ( s.empty() )
76 return false;
77
78 s = wxString::FromUTF8(asciistr, wxString::npos);
79 if ( s.empty() )
80 return false;
81
82 return true;
83 }
84
85 BENCHMARK_FUNC(FromUTF8WithLen)
86 {
87 wxString s = wxString::FromUTF8(utf8str, WXSIZEOF(utf8str));
88 if ( s.empty() )
89 return false;
90
91 s = wxString::FromUTF8(asciistr, WXSIZEOF(asciistr));
92 if ( s.empty() )
93 return false;
94
95 return true;
96 }
97
98 // ----------------------------------------------------------------------------
99 // FromUTF8Unchecked() benchmarks
100 // ----------------------------------------------------------------------------
101
102 BENCHMARK_FUNC(FromUTF8Unchecked)
103 {
104 wxString s = wxString::FromUTF8Unchecked(utf8str);
105 if ( s.empty() )
106 return false;
107
108 s = wxString::FromUTF8Unchecked(asciistr);
109 if ( s.empty() )
110 return false;
111
112 return true;
113 }
114
115 BENCHMARK_FUNC(FromUTF8UncheckedWithNpos)
116 {
117 wxString s = wxString::FromUTF8Unchecked(utf8str, wxString::npos);
118 if ( s.empty() )
119 return false;
120
121 s = wxString::FromUTF8Unchecked(asciistr, wxString::npos);
122 if ( s.empty() )
123 return false;
124
125 return true;
126 }
127
128 BENCHMARK_FUNC(FromUTF8UncheckedWithLen)
129 {
130 wxString s = wxString::FromUTF8Unchecked(utf8str, WXSIZEOF(utf8str));
131 if ( s.empty() )
132 return false;
133
134 s = wxString::FromUTF8Unchecked(asciistr, WXSIZEOF(asciistr));
135 if ( s.empty() )
136 return false;
137
138 return true;
139 }
140
141 // ----------------------------------------------------------------------------
142 // FromAscii() benchmarks
143 // ----------------------------------------------------------------------------
144
145 BENCHMARK_FUNC(FromAscii)
146 {
147 wxString s = wxString::FromAscii(asciistr);
148 if ( s.empty() )
149 return false;
150
151 return true;
152 }
153
154 BENCHMARK_FUNC(FromAsciiWithNpos)
155 {
156 wxString s = wxString::FromAscii(asciistr);
157 if ( s.empty() )
158 return false;
159
160 return true;
161 }
162
163 BENCHMARK_FUNC(FromAsciiWithLen)
164 {
165 wxString s = wxString::FromAscii(asciistr, WXSIZEOF(asciistr));
166 if ( s.empty() )
167 return false;
168
169 return true;
170 }
171
172 // ----------------------------------------------------------------------------
173 // simple string iteration
174 // ----------------------------------------------------------------------------
175
176 // baseline
177 BENCHMARK_FUNC(ForCString)
178 {
179 for ( size_t n = 0; n < WXSIZEOF(asciistr); n++ )
180 {
181 if ( asciistr[n] == '~' )
182 return false;
183 }
184
185 return true;
186 }
187
188 BENCHMARK_FUNC(ForStringIndex)
189 {
190 const wxString s = wxString::FromAscii(asciistr);
191 const size_t len = s.length();
192 for ( size_t n = 0; n < len; n++ )
193 {
194 if ( s[n] == '~' )
195 return false;
196 }
197
198 return true;
199 }
200
201 BENCHMARK_FUNC(ForStringIter)
202 {
203 const wxString s = wxString::FromAscii(asciistr);
204 const wxString::const_iterator end = s.end();
205 for ( wxString::const_iterator i = s.begin(); i != end; ++i )
206 {
207 if ( *i == '~' )
208 return false;
209 }
210
211 return true;
212 }
213
214 BENCHMARK_FUNC(ForStringRIter)
215 {
216 const wxString s = wxString::FromAscii(asciistr);
217 const wxString::const_reverse_iterator rend = s.rend();
218 for ( wxString::const_reverse_iterator i = s.rbegin(); i != rend; ++i )
219 {
220 if ( *i == '~' )
221 return false;
222 }
223
224 return true;
225 }
226
227 // ----------------------------------------------------------------------------
228 // wxString::Replace()
229 // ----------------------------------------------------------------------------
230
231 const size_t ASCIISTR_LEN = strlen(asciistr);
232
233 BENCHMARK_FUNC(ReplaceLoop)
234 {
235 wxString str('x', ASCIISTR_LEN);
236 for ( size_t n = 0; n < ASCIISTR_LEN; n++ )
237 {
238 if ( str[n] == 'a' )
239 str[n] = 'z';
240 }
241
242 return str.length() != 0;
243 }
244
245 BENCHMARK_FUNC(ReplaceNone)
246 {
247 wxString str('x', ASCIISTR_LEN);
248 return str.Replace("a", "z") == 0;
249 }
250
251 BENCHMARK_FUNC(ReplaceSome)
252 {
253 wxString str(asciistr);
254 return str.Replace("7", "8") != 0;
255 }
256
257 BENCHMARK_FUNC(ReplaceAll)
258 {
259 wxString str('x', ASCIISTR_LEN);
260 return str.Replace("x", "y") != 0;
261 }
262
263
264 // ----------------------------------------------------------------------------
265 // string buffers: wx[W]CharBuffer
266 // ----------------------------------------------------------------------------
267
268 BENCHMARK_FUNC(CharBuffer)
269 {
270 wxString str(asciistr);
271
272 // NB: wxStrlen() is here to simulate some use of the returned buffer.
273 // Both mb_str() and wc_str() are used so that this code does something
274 // nontrivial in any build.
275 return wxStrlen(str.mb_str()) == ASCIISTR_LEN &&
276 wxStrlen(str.wc_str()) == ASCIISTR_LEN;
277 }
278
279
280 // ----------------------------------------------------------------------------
281 // wxString::operator[] - parse large HTML page
282 // ----------------------------------------------------------------------------
283
284 class DummyParser : public wx28HtmlParser
285 {
286 public:
287 virtual wxObject* GetProduct() { return NULL; }
288 virtual void AddText(const wxChar*) {}
289 };
290
291
292 BENCHMARK_FUNC(ParseHTML)
293 {
294 // static so that construction time is not counted
295 static DummyParser parser;
296 static wxString html;
297 if ( html.empty() )
298 {
299 wxString html1;
300 wxFFile("htmltest.html").ReadAll(&html1, wxConvUTF8);
301
302 // this is going to make for some invalid HTML, of course, but it
303 // doesn't really matter
304 for ( long n = 0; n < Bench::GetNumericParameter(); n++ )
305 html += html1;
306 }
307
308 parser.Parse(html);
309
310 return true;
311 }