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