1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        printfbench.cpp
3 // Purpose:     benchmarks for wx*Printf*() functions
4 // Author:      Francesco Montorsi
5 // Modified by:
6 // Created:     27/3/2006
7 // Copyright:   (c) 2006-2009 Francesco Montorsi
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 /*
12     TODO: revise the benchmarking functions below to allow valid comparisons
13           between the wx implementation and the system's implementation of
14           the tested functions (e.g. adding tests which use the wxS macro to
15           avoid runtime encoding conversions, etc etc).
16 */
17 
18 //
19 // Profiling under Linux:
20 // =====================
21 //
22 //   1) configure wxWidgets in release mode
23 //   2) make sure that HAVE_UNIX98_PRINTF is undefined (just #defining it to zero
24 //      does not work; you must comment out the entire #define) in your setup.h;
25 //      and also that wxUSE_PRINTF_POS_PARAMS is set to 1; this will force the
26 //      use of wx's own implementation of wxVsnprintf()
27 //   3) compile wx
28 //   4) set wxTEST_WX_ONLY to 1 and compile tests as well
29 //
30 // Now you have two main choices:
31 //
32 //  - using gprof:
33 //      5) add to the Makefile of this test program the -pg option both to
34 //         CXXFLAGS and to LDFLAGS
35 //      6) run the test
36 //      7) look at the gmon.out file with gprof utility
37 //
38 //  - using valgrind:
39 //      4) run "valgrind --tool=callgrind ./printfbench"
40 //      5) run "kcachegrind dump_file_generated_by_callgrind"
41 //
42 
43 #include "wx/string.h"
44 #include "bench.h"
45 
46 // ----------------------------------------------------------------------------
47 // constants
48 // ----------------------------------------------------------------------------
49 
50 #define BUFSIZE                  10000
51 
52 const wxString g_verylongString =
53     "very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very "
54     "very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long string!\n\n\n";
55 
56 
57 // ----------------------------------------------------------------------------
58 // benchmarking helpers
59 // ----------------------------------------------------------------------------
60 
61 #define DO_LONG_BENCHMARK(fnc, prefix)                                                     \
62     fnc(buffer, BUFSIZE,                                                                   \
63         prefix##"This is a reasonably long string with various %s arguments, exactly %d, " \
64         prefix##"and is used as benchmark for %s - %% %.2f %d %s",                                 \
65         prefix##"(many!!)", 6, "this program", 23.342f, 999,                                       \
66         (const char*)g_verylongString.c_str());
67 
68 #define DO_LONG_POSITIONAL_BENCHMARK(fnc, prefix)                                          \
69     fnc(buffer, BUFSIZE,                                                                   \
70         prefix##"This is a %2$s and thus is harder to parse... let's %1$s "                \
71         prefix##"for our benchmarking aims - %% %3$f %5$d %4$s",                                   \
72         prefix##"test it", "string with positional arguments", 23.342f,                            \
73         (const char*)g_verylongString.c_str(), 999);
74 
75 #define DO_BENCHMARK(fnc, prefix)                                                          \
76     fnc(buffer, BUFSIZE, prefix##"This is a short %s string with very few words", "test");
77 
78 #define DO_POSITIONAL_BENCHMARK(fnc, prefix)                                               \
79     fnc(buffer, BUFSIZE,                                                                   \
80         prefix##"This is a %2$s and thus is harder to parse... nonetheless, %1$s !",       \
81         "test it", "string with positional arguments");
82 
83 // the configure script of wxWidgets will define HAVE_UNIX98_PRINTF on those
84 // system with a *printf() family of functions conformant to Unix 98 standard;
85 // systems without the configure script as build system (e.g. Windows) do not
86 // have positional support anyway
87 #ifdef HAVE_UNIX98_PRINTF
88     #define wxSYSTEM_HAS_POSPARAM_SUPPORT   1
89 #else
90     #define wxSYSTEM_HAS_POSPARAM_SUPPORT   1
91 #endif
92 
93 // we need to avoid the use of wxPrintf() here since it could have been mapped
94 // to wxWidgets' implementation of wxVsnPrintf() !
95 #if wxUSE_UNICODE
96     #define sys_printf swprintf
97 #else
98     #define sys_printf snprintf
99 #endif
100 
101 
102 // ----------------------------------------------------------------------------
103 // main
104 // ----------------------------------------------------------------------------
105 
BENCHMARK_FUNC(SnprintfWithPositionals)106 BENCHMARK_FUNC(SnprintfWithPositionals)
107 {
108     wxChar buffer[BUFSIZE];
109 #if wxUSE_PRINTF_POS_PARAMS
110     DO_LONG_POSITIONAL_BENCHMARK(wxSnprintf, )
111     DO_POSITIONAL_BENCHMARK(wxSnprintf, )
112 #endif
113     return true;
114 }
115 
BENCHMARK_FUNC(Snprintf)116 BENCHMARK_FUNC(Snprintf)
117 {
118     wxChar buffer[BUFSIZE];
119     DO_LONG_BENCHMARK(wxSnprintf, )
120     DO_BENCHMARK(wxSnprintf, )
121     return true;
122 }
123 
BENCHMARK_FUNC(SystemSnprintfWithPositionals)124 BENCHMARK_FUNC(SystemSnprintfWithPositionals)
125 {
126     wxChar buffer[BUFSIZE];
127     DO_LONG_POSITIONAL_BENCHMARK(sys_printf, L)
128     DO_POSITIONAL_BENCHMARK(sys_printf, L)
129     return true;
130 }
131 
BENCHMARK_FUNC(SystemSnprintf)132 BENCHMARK_FUNC(SystemSnprintf)
133 {
134     wxChar buffer[BUFSIZE];
135     DO_LONG_BENCHMARK(sys_printf, L)
136     DO_BENCHMARK(sys_printf, L)
137     return true;
138 }
139 
140