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