Add some more cases to the app-id unit tests
[glib.git] / tests / gobject / performance-threaded.c
blobaf6424cae64614533239558453da888f66f56bee
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2009 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 #include <math.h>
19 #include <string.h>
20 #include <glib-object.h>
21 #include "testcommon.h"
23 #define DEFAULT_TEST_TIME 2 /* seconds */
25 static GType
26 simple_register_class (const char *name, GType parent, ...)
28 GInterfaceInfo interface_info = { NULL, NULL, NULL };
29 va_list args;
30 GType type, interface;
32 va_start (args, parent);
33 type = g_type_register_static_simple (parent, name, sizeof (GObjectClass),
34 NULL, parent == G_TYPE_INTERFACE ? 0 : sizeof (GObject), NULL, 0);
35 for (;;)
37 interface = va_arg (args, GType);
38 if (interface == 0)
39 break;
40 g_type_add_interface_static (type, interface, &interface_info);
42 va_end (args);
44 return type;
47 /* test emulating liststore behavior for interface lookups */
49 static GType liststore;
50 static GType liststore_interfaces[6];
52 static gpointer
53 register_types (void)
55 static volatile gsize inited = 0;
56 if (g_once_init_enter (&inited))
58 liststore_interfaces[0] = simple_register_class ("GtkBuildable", G_TYPE_INTERFACE, 0);
59 liststore_interfaces[1] = simple_register_class ("GtkTreeDragDest", G_TYPE_INTERFACE, 0);
60 liststore_interfaces[2] = simple_register_class ("GtkTreeModel", G_TYPE_INTERFACE, 0);
61 liststore_interfaces[3] = simple_register_class ("GtkTreeDragSource", G_TYPE_INTERFACE, 0);
62 liststore_interfaces[4] = simple_register_class ("GtkTreeSortable", G_TYPE_INTERFACE, 0);
63 liststore_interfaces[5] = simple_register_class ("UnrelatedInterface", G_TYPE_INTERFACE, 0);
65 liststore = simple_register_class ("GtkListStore", G_TYPE_OBJECT,
66 liststore_interfaces[0], liststore_interfaces[1], liststore_interfaces[2],
67 liststore_interfaces[3], liststore_interfaces[4], (GType) 0);
69 g_once_init_leave (&inited, 1);
71 return NULL;
74 static void
75 liststore_is_a_run (gpointer data)
77 guint i;
79 for (i = 0; i < 1000; i++)
81 g_assert (g_type_is_a (liststore, liststore_interfaces[0]));
82 g_assert (g_type_is_a (liststore, liststore_interfaces[1]));
83 g_assert (g_type_is_a (liststore, liststore_interfaces[2]));
84 g_assert (g_type_is_a (liststore, liststore_interfaces[3]));
85 g_assert (g_type_is_a (liststore, liststore_interfaces[4]));
86 g_assert (!g_type_is_a (liststore, liststore_interfaces[5]));
90 static gpointer
91 liststore_get_class (void)
93 register_types ();
94 return g_type_class_ref (liststore);
97 static void
98 liststore_interface_peek_run (gpointer klass)
100 guint i;
101 gpointer iface;
103 for (i = 0; i < 1000; i++)
105 iface = g_type_interface_peek (klass, liststore_interfaces[0]);
106 g_assert (iface);
107 iface = g_type_interface_peek (klass, liststore_interfaces[1]);
108 g_assert (iface);
109 iface = g_type_interface_peek (klass, liststore_interfaces[2]);
110 g_assert (iface);
111 iface = g_type_interface_peek (klass, liststore_interfaces[3]);
112 g_assert (iface);
113 iface = g_type_interface_peek (klass, liststore_interfaces[4]);
114 g_assert (iface);
118 static void
119 liststore_interface_peek_same_run (gpointer klass)
121 guint i;
122 gpointer iface;
124 for (i = 0; i < 1000; i++)
126 iface = g_type_interface_peek (klass, liststore_interfaces[0]);
127 g_assert (iface);
128 iface = g_type_interface_peek (klass, liststore_interfaces[0]);
129 g_assert (iface);
130 iface = g_type_interface_peek (klass, liststore_interfaces[0]);
131 g_assert (iface);
132 iface = g_type_interface_peek (klass, liststore_interfaces[0]);
133 g_assert (iface);
134 iface = g_type_interface_peek (klass, liststore_interfaces[0]);
135 g_assert (iface);
139 #if 0
140 /* DUMB test doing nothing */
142 static gpointer
143 no_setup (void)
145 return NULL;
148 static void
149 no_run (gpointer data)
152 #endif
154 static void
155 no_reset (gpointer data)
159 static void
160 no_teardown (gpointer data)
164 typedef struct _PerformanceTest PerformanceTest;
165 struct _PerformanceTest {
166 const char *name;
168 gpointer (*setup) (void);
169 void (*run) (gpointer data);
170 void (*reset) (gpointer data);
171 void (*teardown) (gpointer data);
174 static const PerformanceTest tests[] = {
175 { "liststore-is-a",
176 register_types,
177 liststore_is_a_run,
178 no_reset,
179 no_teardown },
180 { "liststore-interface-peek",
181 liststore_get_class,
182 liststore_interface_peek_run,
183 no_reset,
184 g_type_class_unref },
185 { "liststore-interface-peek-same",
186 liststore_get_class,
187 liststore_interface_peek_same_run,
188 no_reset,
189 g_type_class_unref },
190 #if 0
191 { "nothing",
192 no_setup,
193 no_run,
194 no_reset,
195 no_teardown }
196 #endif
199 static gboolean verbose = FALSE;
200 static int n_threads = 0;
201 static gboolean list = FALSE;
202 static int test_length = DEFAULT_TEST_TIME;
204 static GOptionEntry cmd_entries[] = {
205 {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
206 "Print extra information", NULL},
207 {"threads", 't', 0, G_OPTION_ARG_INT, &n_threads,
208 "number of threads to run in parrallel", NULL},
209 {"seconds", 's', 0, G_OPTION_ARG_INT, &test_length,
210 "Time to run each test in seconds", NULL},
211 {"list", 'l', 0, G_OPTION_ARG_NONE, &list,
212 "List all available tests and exit", NULL},
213 {NULL}
216 static gpointer
217 run_test_thread (gpointer user_data)
219 const PerformanceTest *test = user_data;
220 gpointer data;
221 double elapsed;
222 GTimer *timer, *total;
223 GArray *results;
225 total = g_timer_new ();
226 g_timer_start (total);
228 /* Set up test */
229 timer = g_timer_new ();
230 data = test->setup ();
231 results = g_array_new (FALSE, FALSE, sizeof (double));
233 /* Run the test */
234 while (g_timer_elapsed (total, NULL) < test_length)
236 g_timer_reset (timer);
237 g_timer_start (timer);
238 test->run (data);
239 g_timer_stop (timer);
240 elapsed = g_timer_elapsed (timer, NULL);
241 g_array_append_val (results, elapsed);
242 test->reset (data);
245 /* Tear down */
246 test->teardown (data);
247 g_timer_destroy (timer);
248 g_timer_destroy (total);
250 return results;
253 static int
254 compare_doubles (gconstpointer a, gconstpointer b)
256 double d = *(double *) a - *(double *) b;
258 if (d < 0)
259 return -1;
260 if (d > 0)
261 return 1;
262 return 0;
265 static void
266 print_results (GArray *array)
268 double min, max, avg;
269 guint i;
271 g_array_sort (array, compare_doubles);
273 /* FIXME: discard outliers */
275 min = g_array_index (array, double, 0) * 1000;
276 max = g_array_index (array, double, array->len - 1) * 1000;
277 avg = 0;
278 for (i = 0; i < array->len; i++)
280 avg += g_array_index (array, double, i);
282 avg = avg / array->len * 1000;
284 g_print (" %u runs, min/avg/max = %.3f/%.3f/%.3f ms\n", array->len, min, avg, max);
287 static void
288 run_test (const PerformanceTest *test)
290 GArray *results;
292 g_print ("Running test \"%s\"\n", test->name);
294 if (n_threads == 0) {
295 results = run_test_thread ((gpointer) test);
296 } else {
297 guint i;
298 GThread **threads;
299 GArray *thread_results;
301 threads = g_new (GThread *, n_threads);
302 for (i = 0; i < n_threads; i++) {
303 threads[i] = g_thread_create (run_test_thread, (gpointer) test, TRUE, NULL);
304 g_assert (threads[i] != NULL);
307 results = g_array_new (FALSE, FALSE, sizeof (double));
308 for (i = 0; i < n_threads; i++) {
309 thread_results = g_thread_join (threads[i]);
310 g_array_append_vals (results, thread_results->data, thread_results->len);
311 g_array_free (thread_results, TRUE);
313 g_free (threads);
316 print_results (results);
317 g_array_free (results, TRUE);
320 static const PerformanceTest *
321 find_test (const char *name)
323 int i;
324 for (i = 0; i < G_N_ELEMENTS (tests); i++)
326 if (strcmp (tests[i].name, name) == 0)
327 return &tests[i];
329 return NULL;
333 main (int argc,
334 char *argv[])
336 const PerformanceTest *test;
337 GOptionContext *context;
338 GError *error = NULL;
339 int i;
341 context = g_option_context_new ("GObject performance tests");
342 g_option_context_add_main_entries (context, cmd_entries, NULL);
343 if (!g_option_context_parse (context, &argc, &argv, &error))
345 g_printerr ("%s: %s\n", argv[0], error->message);
346 return 1;
349 if (list)
351 for (i = 0; i < G_N_ELEMENTS (tests); i++)
353 g_print ("%s\n", tests[i].name);
355 return 0;
358 if (argc > 1)
360 for (i = 1; i < argc; i++)
362 test = find_test (argv[i]);
363 if (test)
364 run_test (test);
367 else
369 for (i = 0; i < G_N_ELEMENTS (tests); i++)
370 run_test (&tests[i]);
373 return 0;