Branch data Line data Source code
1 : : /* GObject - GLib Type, Object, Parameter and Signal Library
2 : : * Copyright (C) 2009 Red Hat, Inc.
3 : : * Copyright (C) 2022 Canonical Ltd.
4 : : *
5 : : * This library is free software; you can redistribute it and/or
6 : : * modify it under the terms of the GNU Lesser General Public
7 : : * License as published by the Free Software Foundation; either
8 : : * version 2.1 of the License, or (at your option) any later version.
9 : : *
10 : : * This library is distributed in the hope that it will be useful,
11 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : : * Lesser General Public License for more details.
14 : : *
15 : : * You should have received a copy of the GNU Lesser General
16 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 : : */
18 : :
19 : : #include <math.h>
20 : : #include <string.h>
21 : : #include <glib-object.h>
22 : : #include "../testcommon.h"
23 : :
24 : : #define WARM_UP_N_RUNS 50
25 : : #define ESTIMATE_ROUND_TIME_N_RUNS 5
26 : : #define DEFAULT_TEST_TIME 15 /* seconds */
27 : : /* The time we want each round to take, in seconds, this should
28 : : * be large enough compared to the timer resolution, but small
29 : : * enough that the risk of any random slowness will miss the
30 : : * running window */
31 : : #define TARGET_ROUND_TIME 0.008
32 : :
33 : : static gboolean verbose = FALSE;
34 : : static int test_length = DEFAULT_TEST_TIME;
35 : :
36 : : static GOptionEntry cmd_entries[] = {
37 : : {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
38 : : "Print extra information", NULL},
39 : : {"seconds", 's', 0, G_OPTION_ARG_INT, &test_length,
40 : : "Time to run each test in seconds", NULL},
41 : : G_OPTION_ENTRY_NULL
42 : : };
43 : :
44 : : typedef struct _PerformanceTest PerformanceTest;
45 : : struct _PerformanceTest {
46 : : const char *name;
47 : : gpointer extra_data;
48 : :
49 : : gpointer (*setup) (PerformanceTest *test);
50 : : void (*init) (PerformanceTest *test,
51 : : gpointer data,
52 : : double factor);
53 : : void (*run) (PerformanceTest *test,
54 : : gpointer data);
55 : : void (*finish) (PerformanceTest *test,
56 : : gpointer data);
57 : : void (*teardown) (PerformanceTest *test,
58 : : gpointer data);
59 : : void (*print_result) (PerformanceTest *test,
60 : : gpointer data,
61 : : double time);
62 : : };
63 : :
64 : : static void
65 : 24 : run_test (PerformanceTest *test)
66 : : {
67 : 24 : gpointer data = NULL;
68 : : guint64 i, num_rounds;
69 : : double elapsed, min_elapsed, max_elapsed, avg_elapsed, factor;
70 : : GTimer *timer;
71 : :
72 : 24 : g_print ("Running test %s\n", test->name);
73 : :
74 : : /* Set up test */
75 : 24 : timer = g_timer_new ();
76 : 24 : data = test->setup (test);
77 : :
78 [ - + ]: 24 : if (verbose)
79 : 0 : g_print ("Warming up\n");
80 : :
81 : 24 : g_timer_start (timer);
82 : :
83 : : /* Warm up the test by doing a few runs */
84 [ + + ]: 1224 : for (i = 0; i < WARM_UP_N_RUNS; i++)
85 : : {
86 : 1200 : test->init (test, data, 1.0);
87 : 1200 : test->run (test, data);
88 : 1200 : test->finish (test, data);
89 : : }
90 : :
91 : 24 : g_timer_stop (timer);
92 : 24 : elapsed = g_timer_elapsed (timer, NULL);
93 : :
94 [ - + ]: 24 : if (verbose)
95 : : {
96 : 0 : g_print ("Warm up time: %.2f secs\n", elapsed);
97 : 0 : g_print ("Estimating round time\n");
98 : : }
99 : :
100 : : /* Estimate time for one run by doing a few test rounds */
101 : 24 : min_elapsed = 0;
102 [ + + ]: 144 : for (i = 0; i < ESTIMATE_ROUND_TIME_N_RUNS; i++)
103 : : {
104 : 120 : test->init (test, data, 1.0);
105 : 120 : g_timer_start (timer);
106 : 120 : test->run (test, data);
107 : 120 : g_timer_stop (timer);
108 : 120 : test->finish (test, data);
109 : :
110 : 120 : elapsed = g_timer_elapsed (timer, NULL);
111 [ + + ]: 120 : if (i == 0)
112 : 24 : min_elapsed = elapsed;
113 : : else
114 [ + + ]: 96 : min_elapsed = MIN (min_elapsed, elapsed);
115 : : }
116 : :
117 : 24 : factor = TARGET_ROUND_TIME / min_elapsed;
118 : :
119 [ - + ]: 24 : if (verbose)
120 : 0 : g_print ("Uncorrected round time: %.4f msecs, correction factor %.2f\n", 1000*min_elapsed, factor);
121 : :
122 : : /* Calculate number of rounds needed */
123 : 24 : num_rounds = (test_length / TARGET_ROUND_TIME) + 1;
124 : :
125 [ - + ]: 24 : if (verbose)
126 : 0 : g_print ("Running %"G_GINT64_MODIFIER"d rounds\n", num_rounds);
127 : :
128 : : /* Run the test */
129 : 24 : avg_elapsed = 0.0;
130 : 24 : min_elapsed = 0.0;
131 : 24 : max_elapsed = 0.0;
132 [ + + ]: 48 : for (i = 0; i < num_rounds; i++)
133 : : {
134 : 24 : test->init (test, data, factor);
135 : 24 : g_timer_start (timer);
136 : 24 : test->run (test, data);
137 : 24 : g_timer_stop (timer);
138 : 24 : test->finish (test, data);
139 : 24 : elapsed = g_timer_elapsed (timer, NULL);
140 : :
141 [ + - ]: 24 : if (i == 0)
142 : 24 : max_elapsed = min_elapsed = avg_elapsed = elapsed;
143 : : else
144 : : {
145 [ # # ]: 0 : min_elapsed = MIN (min_elapsed, elapsed);
146 [ # # ]: 0 : max_elapsed = MAX (max_elapsed, elapsed);
147 : 0 : avg_elapsed += elapsed;
148 : : }
149 : : }
150 : :
151 [ - + ]: 24 : if (num_rounds > 1)
152 : 0 : avg_elapsed = avg_elapsed / num_rounds;
153 : :
154 [ - + ]: 24 : if (verbose)
155 : : {
156 : 0 : g_print ("Minimum corrected round time: %.2f msecs\n", min_elapsed * 1000);
157 : 0 : g_print ("Maximum corrected round time: %.2f msecs\n", max_elapsed * 1000);
158 : 0 : g_print ("Average corrected round time: %.2f msecs\n", avg_elapsed * 1000);
159 : : }
160 : :
161 : : /* Print the results */
162 : 24 : test->print_result (test, data, min_elapsed);
163 : :
164 : : /* Tear down */
165 : 24 : test->teardown (test, data);
166 : 24 : g_timer_destroy (timer);
167 : 24 : }
168 : :
169 : : /*************************************************************
170 : : * Simple object is a very simple small GObject subclass
171 : : * with no properties, no signals, implementing no interfaces
172 : : *************************************************************/
173 : :
174 : : static GType simple_object_get_type (void);
175 : : #define SIMPLE_TYPE_OBJECT (simple_object_get_type ())
176 : : typedef struct _SimpleObject SimpleObject;
177 : : typedef struct _SimpleObjectClass SimpleObjectClass;
178 : :
179 : : struct _SimpleObject
180 : : {
181 : : GObject parent_instance;
182 : : int val;
183 : : };
184 : :
185 : : struct _SimpleObjectClass
186 : : {
187 : : GObjectClass parent_class;
188 : : };
189 : :
190 [ + + + - : 5 : G_DEFINE_TYPE (SimpleObject, simple_object, G_TYPE_OBJECT)
+ + ]
191 : :
192 : : static void
193 : 1135766 : simple_object_finalize (GObject *object)
194 : : {
195 : 1135766 : G_OBJECT_CLASS (simple_object_parent_class)->finalize (object);
196 : 1135766 : }
197 : :
198 : : static void
199 : 1 : simple_object_class_init (SimpleObjectClass *class)
200 : : {
201 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (class);
202 : :
203 : 1 : object_class->finalize = simple_object_finalize;
204 : 1 : }
205 : :
206 : : static void
207 : 1135766 : simple_object_init (SimpleObject *simple_object)
208 : : {
209 : 1135766 : simple_object->val = 42;
210 : 1135766 : }
211 : :
212 : : typedef struct _TestIfaceClass TestIfaceClass;
213 : : typedef struct _TestIfaceClass TestIface1Class;
214 : : typedef struct _TestIfaceClass TestIface2Class;
215 : : typedef struct _TestIfaceClass TestIface3Class;
216 : : typedef struct _TestIfaceClass TestIface4Class;
217 : : typedef struct _TestIfaceClass TestIface5Class;
218 : : typedef struct _TestIface TestIface;
219 : :
220 : : struct _TestIfaceClass
221 : : {
222 : : GTypeInterface base_iface;
223 : : void (*method) (TestIface *obj);
224 : : };
225 : :
226 : : static GType test_iface1_get_type (void);
227 : : static GType test_iface2_get_type (void);
228 : : static GType test_iface3_get_type (void);
229 : : static GType test_iface4_get_type (void);
230 : : static GType test_iface5_get_type (void);
231 : :
232 : : #define TEST_TYPE_IFACE1 (test_iface1_get_type ())
233 : : #define TEST_TYPE_IFACE2 (test_iface2_get_type ())
234 : : #define TEST_TYPE_IFACE3 (test_iface3_get_type ())
235 : : #define TEST_TYPE_IFACE4 (test_iface4_get_type ())
236 : : #define TEST_TYPE_IFACE5 (test_iface5_get_type ())
237 : :
238 [ + + ]: 57 : static DEFINE_IFACE (TestIface1, test_iface1, NULL, NULL)
239 [ + + ]: 57 : static DEFINE_IFACE (TestIface2, test_iface2, NULL, NULL)
240 [ + + ]: 57 : static DEFINE_IFACE (TestIface3, test_iface3, NULL, NULL)
241 [ + + ]: 57 : static DEFINE_IFACE (TestIface4, test_iface4, NULL, NULL)
242 [ + + ]: 57 : static DEFINE_IFACE (TestIface5, test_iface5, NULL, NULL)
243 : :
244 : : /*************************************************************
245 : : * Complex object is a GObject subclass with a properties,
246 : : * construct properties, signals and implementing an interface.
247 : : *************************************************************/
248 : :
249 : : static GType complex_object_get_type (void);
250 : : #define COMPLEX_TYPE_OBJECT (complex_object_get_type ())
251 : : typedef struct _ComplexObject ComplexObject;
252 : : typedef struct _ComplexObjectClass ComplexObjectClass;
253 : :
254 : : struct _ComplexObject
255 : : {
256 : : GObject parent_instance;
257 : : int val1;
258 : : char *val2;
259 : : };
260 : :
261 : : struct _ComplexObjectClass
262 : : {
263 : : GObjectClass parent_class;
264 : :
265 : : void (*signal) (ComplexObject *obj);
266 : : void (*signal_empty) (ComplexObject *obj);
267 : : };
268 : :
269 : : static void complex_test_iface_init (gpointer g_iface,
270 : : gpointer iface_data);
271 : :
272 [ + + + - : 5113895 : G_DEFINE_TYPE_EXTENDED (ComplexObject, complex_object,
+ + ]
273 : : G_TYPE_OBJECT, 0,
274 : : G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE1, complex_test_iface_init)
275 : : G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE2, complex_test_iface_init)
276 : : G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE3, complex_test_iface_init)
277 : : G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE4, complex_test_iface_init)
278 : : G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE5, complex_test_iface_init))
279 : :
280 : : #define COMPLEX_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), COMPLEX_TYPE_OBJECT, ComplexObject))
281 : :
282 : : enum {
283 : : PROP_0,
284 : : PROP_VAL1,
285 : : PROP_VAL2,
286 : : N_PROPERTIES
287 : : };
288 : :
289 : : static GParamSpec *pspecs[N_PROPERTIES] = { NULL, };
290 : :
291 : : enum {
292 : : COMPLEX_SIGNAL,
293 : : COMPLEX_SIGNAL_EMPTY,
294 : : COMPLEX_SIGNAL_GENERIC,
295 : : COMPLEX_SIGNAL_GENERIC_EMPTY,
296 : : COMPLEX_SIGNAL_ARGS,
297 : : COMPLEX_LAST_SIGNAL
298 : : };
299 : :
300 : : static guint complex_signals[COMPLEX_LAST_SIGNAL] = { 0 };
301 : :
302 : : static void
303 : 1697665 : complex_object_finalize (GObject *object)
304 : : {
305 : 1697665 : ComplexObject *c = COMPLEX_OBJECT (object);
306 : :
307 : 1697665 : g_free (c->val2);
308 : :
309 : 1697665 : G_OBJECT_CLASS (complex_object_parent_class)->finalize (object);
310 : 1697665 : }
311 : :
312 : : static void
313 : 2836368 : complex_object_set_property (GObject *object,
314 : : guint prop_id,
315 : : const GValue *value,
316 : : GParamSpec *pspec)
317 : : {
318 : 2836368 : ComplexObject *complex = COMPLEX_OBJECT (object);
319 : :
320 [ + + - ]: 2836368 : switch (prop_id)
321 : : {
322 : 2276724 : case PROP_VAL1:
323 : 2276724 : complex->val1 = g_value_get_int (value);
324 : 2276724 : break;
325 : 559644 : case PROP_VAL2:
326 : 559644 : g_free (complex->val2);
327 : 559644 : complex->val2 = g_value_dup_string (value);
328 : 559644 : break;
329 : 0 : default:
330 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
331 : 0 : break;
332 : : }
333 : 2836368 : }
334 : :
335 : : static void
336 : 579839 : complex_object_get_property (GObject *object,
337 : : guint prop_id,
338 : : GValue *value,
339 : : GParamSpec *pspec)
340 : : {
341 : 579839 : ComplexObject *complex = COMPLEX_OBJECT (object);
342 : :
343 [ + - - ]: 579839 : switch (prop_id)
344 : : {
345 : 579839 : case PROP_VAL1:
346 : 579839 : g_value_set_int (value, complex->val1);
347 : 579839 : break;
348 : 0 : case PROP_VAL2:
349 : 0 : g_value_set_string (value, complex->val2);
350 : 0 : break;
351 : 0 : default:
352 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
353 : 0 : break;
354 : : }
355 : 579839 : }
356 : :
357 : : static void
358 : 3378400 : complex_object_real_signal (ComplexObject *obj)
359 : : {
360 : 3378400 : }
361 : :
362 : : static void
363 : 1 : complex_object_class_init (ComplexObjectClass *class)
364 : : {
365 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (class);
366 : :
367 : 1 : object_class->finalize = complex_object_finalize;
368 : 1 : object_class->set_property = complex_object_set_property;
369 : 1 : object_class->get_property = complex_object_get_property;
370 : :
371 : 1 : class->signal = complex_object_real_signal;
372 : :
373 : 1 : complex_signals[COMPLEX_SIGNAL] =
374 : 1 : g_signal_new ("signal",
375 : : G_TYPE_FROM_CLASS (object_class),
376 : : G_SIGNAL_RUN_FIRST,
377 : : G_STRUCT_OFFSET (ComplexObjectClass, signal),
378 : : NULL, NULL,
379 : : g_cclosure_marshal_VOID__VOID,
380 : : G_TYPE_NONE, 0);
381 : :
382 : 1 : complex_signals[COMPLEX_SIGNAL_EMPTY] =
383 : 1 : g_signal_new ("signal-empty",
384 : : G_TYPE_FROM_CLASS (object_class),
385 : : G_SIGNAL_RUN_FIRST,
386 : : G_STRUCT_OFFSET (ComplexObjectClass, signal_empty),
387 : : NULL, NULL,
388 : : g_cclosure_marshal_VOID__VOID,
389 : : G_TYPE_NONE, 0);
390 : :
391 : 1 : complex_signals[COMPLEX_SIGNAL_GENERIC] =
392 : 1 : g_signal_new ("signal-generic",
393 : : G_TYPE_FROM_CLASS (object_class),
394 : : G_SIGNAL_RUN_FIRST,
395 : : G_STRUCT_OFFSET (ComplexObjectClass, signal),
396 : : NULL, NULL,
397 : : NULL,
398 : : G_TYPE_NONE, 0);
399 : 1 : complex_signals[COMPLEX_SIGNAL_GENERIC_EMPTY] =
400 : 1 : g_signal_new ("signal-generic-empty",
401 : : G_TYPE_FROM_CLASS (object_class),
402 : : G_SIGNAL_RUN_FIRST,
403 : : G_STRUCT_OFFSET (ComplexObjectClass, signal_empty),
404 : : NULL, NULL,
405 : : NULL,
406 : : G_TYPE_NONE, 0);
407 : :
408 : 1 : complex_signals[COMPLEX_SIGNAL_ARGS] =
409 : 1 : g_signal_new ("signal-args",
410 : : G_TYPE_FROM_CLASS (object_class),
411 : : G_SIGNAL_RUN_FIRST,
412 : : G_STRUCT_OFFSET (ComplexObjectClass, signal),
413 : : NULL, NULL,
414 : : g_cclosure_marshal_VOID__UINT_POINTER,
415 : : G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER);
416 : :
417 : 1 : pspecs[PROP_VAL1] = g_param_spec_int ("val1", "val1", "val1",
418 : : 0, G_MAXINT, 42,
419 : : G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
420 : 1 : pspecs[PROP_VAL2] = g_param_spec_string ("val2", "val2", "val2",
421 : : NULL,
422 : : G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
423 : :
424 : 1 : g_object_class_install_properties (object_class, N_PROPERTIES, pspecs);
425 : 1 : }
426 : :
427 : : static void
428 : 0 : complex_object_iface_method (TestIface *obj)
429 : : {
430 : 0 : ComplexObject *complex = COMPLEX_OBJECT (obj);
431 : 0 : complex->val1++;
432 : 0 : }
433 : :
434 : : static void
435 : 5 : complex_test_iface_init (gpointer g_iface,
436 : : gpointer iface_data)
437 : : {
438 : 5 : TestIfaceClass *iface = g_iface;
439 : 5 : iface->method = complex_object_iface_method;
440 : 5 : }
441 : :
442 : : static void
443 : 1697665 : complex_object_init (ComplexObject *complex_object)
444 : : {
445 : 1697665 : complex_object->val1 = 42;
446 : 1697665 : }
447 : :
448 : : /*************************************************************
449 : : * Test object construction performance
450 : : *************************************************************/
451 : :
452 : : #define NUM_OBJECT_TO_CONSTRUCT 10000
453 : :
454 : : struct ConstructionTest {
455 : : GObject **objects;
456 : : int n_objects;
457 : : GType type;
458 : : };
459 : :
460 : : static gpointer
461 : 6 : test_construction_setup (PerformanceTest *test)
462 : : {
463 : : struct ConstructionTest *data;
464 : :
465 : 6 : data = g_new0 (struct ConstructionTest, 1);
466 : 6 : data->type = ((GType (*)(void))test->extra_data)();
467 : :
468 : 6 : return data;
469 : : }
470 : :
471 : : static void
472 : 280 : test_construction_init (PerformanceTest *test,
473 : : gpointer _data,
474 : : double count_factor)
475 : : {
476 : 280 : struct ConstructionTest *data = _data;
477 : : int n;
478 : :
479 : 280 : n = NUM_OBJECT_TO_CONSTRUCT * count_factor;
480 [ + + ]: 280 : if (data->n_objects != n)
481 : : {
482 : 10 : data->n_objects = n;
483 : 10 : data->objects = g_renew (GObject *, data->objects, n);
484 : : }
485 : 280 : }
486 : :
487 : : static void
488 : 56 : test_construction_run (PerformanceTest *test,
489 : : gpointer _data)
490 : : {
491 : 56 : struct ConstructionTest *data = _data;
492 : 56 : GObject **objects = data->objects;
493 : 56 : GType type = data->type;
494 : : int i, n_objects;
495 : :
496 : 56 : n_objects = data->n_objects;
497 [ + + ]: 584302 : for (i = 0; i < n_objects; i++)
498 : 584246 : objects[i] = g_object_new (type, NULL);
499 : 56 : }
500 : :
501 : : static void
502 : 56 : test_construction_run1 (PerformanceTest *test,
503 : : gpointer _data)
504 : : {
505 : 56 : struct ConstructionTest *data = _data;
506 : 56 : GObject **objects = data->objects;
507 : : int i, n_objects;
508 : :
509 : 56 : n_objects = data->n_objects;
510 [ + + ]: 630136 : for (i = 0; i < n_objects; i++)
511 : 630080 : objects[i] = (GObject *) g_slice_new0 (SimpleObject);
512 : 56 : }
513 : :
514 : : static void
515 : 56 : test_complex_construction_run (PerformanceTest *test,
516 : : gpointer _data)
517 : : {
518 : 56 : struct ConstructionTest *data = _data;
519 : 56 : GObject **objects = data->objects;
520 : 56 : GType type = data->type;
521 : : int i, n_objects;
522 : :
523 : 56 : n_objects = data->n_objects;
524 [ + + ]: 559700 : for (i = 0; i < n_objects; i++)
525 : 559644 : objects[i] = g_object_new (type, "val1", 5, "val2", "thousand", NULL);
526 : 56 : }
527 : :
528 : : static void
529 : 56 : test_complex_construction_run1 (PerformanceTest *test,
530 : : gpointer _data)
531 : : {
532 : 56 : struct ConstructionTest *data = _data;
533 : 56 : GObject **objects = data->objects;
534 : 56 : GType type = data->type;
535 : : int i, n_objects;
536 : :
537 : 56 : n_objects = data->n_objects;
538 [ + + ]: 567023 : for (i = 0; i < n_objects; i++)
539 : : {
540 : : ComplexObject *object;
541 : 566967 : object = (ComplexObject *)g_object_new (type, NULL);
542 : 566967 : object->val1 = 5;
543 : 566967 : object->val2 = g_strdup ("thousand");
544 : 566967 : objects[i] = (GObject *)object;
545 : : }
546 : 56 : }
547 : :
548 : : static void
549 : 56 : test_complex_construction_run2 (PerformanceTest *test,
550 : : gpointer _data)
551 : : {
552 : 56 : struct ConstructionTest *data = _data;
553 : 56 : GObject **objects = data->objects;
554 : 56 : GType type = data->type;
555 : : int i, n_objects;
556 : :
557 : 56 : n_objects = data->n_objects;
558 [ + + ]: 571092 : for (i = 0; i < n_objects; i++)
559 : : {
560 : 571036 : objects[i] = g_object_new (type, NULL);
561 : : }
562 : 56 : }
563 : :
564 : : static void
565 : 224 : test_construction_finish (PerformanceTest *test,
566 : : gpointer _data)
567 : : {
568 : 224 : struct ConstructionTest *data = _data;
569 : : int i;
570 : :
571 [ + + ]: 2282117 : for (i = 0; i < data->n_objects; i++)
572 : 2281893 : g_object_unref (data->objects[i]);
573 : 224 : }
574 : :
575 : : static void
576 : 56 : test_construction_finish1 (PerformanceTest *test,
577 : : gpointer _data)
578 : : {
579 : 56 : struct ConstructionTest *data = _data;
580 : : int i;
581 : :
582 [ + + ]: 630136 : for (i = 0; i < data->n_objects; i++)
583 : 630080 : g_slice_free (SimpleObject, (SimpleObject *)data->objects[i]);
584 : 56 : }
585 : :
586 : : static void
587 : 6 : test_construction_teardown (PerformanceTest *test,
588 : : gpointer _data)
589 : : {
590 : 6 : struct ConstructionTest *data = _data;
591 : 6 : g_free (data->objects);
592 : 6 : g_free (data);
593 : 6 : }
594 : :
595 : : static void
596 : 56 : test_finalization_init (PerformanceTest *test,
597 : : gpointer _data,
598 : : double count_factor)
599 : : {
600 : 56 : struct ConstructionTest *data = _data;
601 : : int n;
602 : :
603 : 56 : n = NUM_OBJECT_TO_CONSTRUCT * count_factor;
604 [ + + ]: 56 : if (data->n_objects != n)
605 : : {
606 : 2 : data->n_objects = n;
607 : 2 : data->objects = g_renew (GObject *, data->objects, n);
608 : : }
609 : :
610 [ + + ]: 551576 : for (int i = 0; i < data->n_objects; i++)
611 : : {
612 : 551520 : data->objects[i] = g_object_new (data->type, NULL);
613 : : }
614 : 56 : }
615 : :
616 : : static void
617 : 56 : test_finalization_run (PerformanceTest *test,
618 : : gpointer _data)
619 : : {
620 : 56 : struct ConstructionTest *data = _data;
621 : 56 : GObject **objects = data->objects;
622 : : int i, n_objects;
623 : :
624 : 56 : n_objects = data->n_objects;
625 [ + + ]: 551576 : for (i = 0; i < n_objects; i++)
626 : : {
627 : 551520 : g_object_unref (objects[i]);
628 : : }
629 : 56 : }
630 : :
631 : : static void
632 : 56 : test_finalization_finish (PerformanceTest *test,
633 : : gpointer _data)
634 : : {
635 : 56 : }
636 : :
637 : : static void
638 : 5 : test_construction_print_result (PerformanceTest *test,
639 : : gpointer _data,
640 : : double time)
641 : : {
642 : 5 : struct ConstructionTest *data = _data;
643 : :
644 : 5 : g_print ("Millions of constructed objects per second: %.3f\n",
645 : 5 : data->n_objects / (time * 1000000));
646 : 5 : }
647 : :
648 : : static void
649 : 1 : test_finalization_print_result (PerformanceTest *test,
650 : : gpointer _data,
651 : : double time)
652 : : {
653 : 1 : struct ConstructionTest *data = _data;
654 : :
655 : 1 : g_print ("Millions of finalized objects per second: %.3f\n",
656 : 1 : data->n_objects / (time * 1000000));
657 : 1 : }
658 : :
659 : : /*************************************************************
660 : : * Test runtime type check performance
661 : : *************************************************************/
662 : :
663 : : #define NUM_KILO_CHECKS_PER_ROUND 50
664 : :
665 : : struct TypeCheckTest {
666 : : GObject *object;
667 : : int n_checks;
668 : : };
669 : :
670 : : static gpointer
671 : 1 : test_type_check_setup (PerformanceTest *test)
672 : : {
673 : : struct TypeCheckTest *data;
674 : :
675 : 1 : data = g_new0 (struct TypeCheckTest, 1);
676 : 1 : data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
677 : :
678 : 1 : return data;
679 : : }
680 : :
681 : : static void
682 : 56 : test_type_check_init (PerformanceTest *test,
683 : : gpointer _data,
684 : : double factor)
685 : : {
686 : 56 : struct TypeCheckTest *data = _data;
687 : :
688 : 56 : data->n_checks = factor * NUM_KILO_CHECKS_PER_ROUND;
689 : 56 : }
690 : :
691 : :
692 : : /* Work around g_type_check_instance_is_a being marked "pure",
693 : : and thus only called once for the loop. */
694 : : gboolean (*my_type_check_instance_is_a) (GTypeInstance *type_instance,
695 : : GType iface_type) = &g_type_check_instance_is_a;
696 : :
697 : : static void
698 : 56 : test_type_check_run (PerformanceTest *test,
699 : : gpointer _data)
700 : : {
701 : 56 : struct TypeCheckTest *data = _data;
702 : 56 : GObject *object = data->object;
703 : : GType type, types[5];
704 : : int i, j;
705 : :
706 : 56 : types[0] = test_iface1_get_type ();
707 : 56 : types[1] = test_iface2_get_type ();
708 : 56 : types[2] = test_iface3_get_type ();
709 : 56 : types[3] = test_iface4_get_type ();
710 : 56 : types[4] = test_iface5_get_type ();
711 : :
712 [ + + ]: 2927 : for (i = 0; i < data->n_checks; i++)
713 : : {
714 : 2871 : type = types[i%5];
715 [ + + ]: 2873871 : for (j = 0; j < 1000; j++)
716 : : {
717 : 2871000 : my_type_check_instance_is_a ((GTypeInstance *)object,
718 : : type);
719 : : }
720 : : }
721 : 56 : }
722 : :
723 : : static void
724 : 56 : test_type_check_finish (PerformanceTest *test,
725 : : gpointer data)
726 : : {
727 : 56 : }
728 : :
729 : : static void
730 : 1 : test_type_check_print_result (PerformanceTest *test,
731 : : gpointer _data,
732 : : double time)
733 : : {
734 : 1 : struct TypeCheckTest *data = _data;
735 : 1 : g_print ("Million type checks per second: %.2f\n",
736 : 1 : data->n_checks / (1000*time));
737 : 1 : }
738 : :
739 : : static void
740 : 1 : test_type_check_teardown (PerformanceTest *test,
741 : : gpointer _data)
742 : : {
743 : 1 : struct TypeCheckTest *data = _data;
744 : :
745 : 1 : g_object_unref (data->object);
746 : 1 : g_free (data);
747 : 1 : }
748 : :
749 : : /*************************************************************
750 : : * Test signal emissions performance (common code)
751 : : *************************************************************/
752 : :
753 : : #define NUM_EMISSIONS_PER_ROUND 10000
754 : :
755 : : struct EmissionTest {
756 : : GObject *object;
757 : : int n_checks;
758 : : int signal_id;
759 : : };
760 : :
761 : : static void
762 : 448 : test_emission_run (PerformanceTest *test,
763 : : gpointer _data)
764 : : {
765 : 448 : struct EmissionTest *data = _data;
766 : 448 : GObject *object = data->object;
767 : : int i;
768 : :
769 [ + + ]: 4665754 : for (i = 0; i < data->n_checks; i++)
770 : 4665306 : g_signal_emit (object, data->signal_id, 0);
771 : 448 : }
772 : :
773 : : static void
774 : 112 : test_emission_run_args (PerformanceTest *test,
775 : : gpointer _data)
776 : : {
777 : 112 : struct EmissionTest *data = _data;
778 : 112 : GObject *object = data->object;
779 : : int i;
780 : :
781 [ + + ]: 1119093 : for (i = 0; i < data->n_checks; i++)
782 : 1118981 : g_signal_emit (object, data->signal_id, 0, 0, NULL);
783 : 112 : }
784 : :
785 : : /*************************************************************
786 : : * Test signal unhandled emissions performance
787 : : *************************************************************/
788 : :
789 : : static gpointer
790 : 5 : test_emission_unhandled_setup (PerformanceTest *test)
791 : : {
792 : : struct EmissionTest *data;
793 : :
794 : 5 : data = g_new0 (struct EmissionTest, 1);
795 : 5 : data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
796 : 5 : data->signal_id = complex_signals[GPOINTER_TO_INT (test->extra_data)];
797 : 5 : return data;
798 : : }
799 : :
800 : : static void
801 : 280 : test_emission_unhandled_init (PerformanceTest *test,
802 : : gpointer _data,
803 : : double factor)
804 : : {
805 : 280 : struct EmissionTest *data = _data;
806 : :
807 : 280 : data->n_checks = factor * NUM_EMISSIONS_PER_ROUND;
808 : 280 : }
809 : :
810 : : static void
811 : 280 : test_emission_unhandled_finish (PerformanceTest *test,
812 : : gpointer data)
813 : : {
814 : 280 : }
815 : :
816 : : static void
817 : 5 : test_emission_unhandled_print_result (PerformanceTest *test,
818 : : gpointer _data,
819 : : double time)
820 : : {
821 : 5 : struct EmissionTest *data = _data;
822 : :
823 : 5 : g_print ("Emissions per second: %.0f\n",
824 : 5 : data->n_checks / time);
825 : 5 : }
826 : :
827 : : static void
828 : 5 : test_emission_unhandled_teardown (PerformanceTest *test,
829 : : gpointer _data)
830 : : {
831 : 5 : struct EmissionTest *data = _data;
832 : :
833 : 5 : g_object_unref (data->object);
834 : 5 : g_free (data);
835 : 5 : }
836 : :
837 : : /*************************************************************
838 : : * Test signal handled emissions performance
839 : : *************************************************************/
840 : :
841 : : static void
842 : 2797241 : test_emission_handled_handler (ComplexObject *obj, gpointer data)
843 : : {
844 : 2797241 : }
845 : :
846 : : static gpointer
847 : 5 : test_emission_handled_setup (PerformanceTest *test)
848 : : {
849 : : struct EmissionTest *data;
850 : :
851 : 5 : data = g_new0 (struct EmissionTest, 1);
852 : 5 : data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
853 : 5 : data->signal_id = complex_signals[GPOINTER_TO_INT (test->extra_data)];
854 : 5 : g_signal_connect (data->object, "signal",
855 : : G_CALLBACK (test_emission_handled_handler),
856 : : NULL);
857 : 5 : g_signal_connect (data->object, "signal-empty",
858 : : G_CALLBACK (test_emission_handled_handler),
859 : : NULL);
860 : 5 : g_signal_connect (data->object, "signal-generic",
861 : : G_CALLBACK (test_emission_handled_handler),
862 : : NULL);
863 : 5 : g_signal_connect (data->object, "signal-generic-empty",
864 : : G_CALLBACK (test_emission_handled_handler),
865 : : NULL);
866 : 5 : g_signal_connect (data->object, "signal-args",
867 : : G_CALLBACK (test_emission_handled_handler),
868 : : NULL);
869 : :
870 : 5 : return data;
871 : : }
872 : :
873 : : static void
874 : 280 : test_emission_handled_init (PerformanceTest *test,
875 : : gpointer _data,
876 : : double factor)
877 : : {
878 : 280 : struct EmissionTest *data = _data;
879 : :
880 : 280 : data->n_checks = factor * NUM_EMISSIONS_PER_ROUND;
881 : 280 : }
882 : :
883 : : static void
884 : 280 : test_emission_handled_finish (PerformanceTest *test,
885 : : gpointer data)
886 : : {
887 : 280 : }
888 : :
889 : : static void
890 : 5 : test_emission_handled_print_result (PerformanceTest *test,
891 : : gpointer _data,
892 : : double time)
893 : : {
894 : 5 : struct EmissionTest *data = _data;
895 : :
896 : 5 : g_print ("Emissions per second: %.0f\n",
897 : 5 : data->n_checks / time);
898 : 5 : }
899 : :
900 : : static void
901 : 5 : test_emission_handled_teardown (PerformanceTest *test,
902 : : gpointer _data)
903 : : {
904 : 5 : struct EmissionTest *data = _data;
905 : :
906 : 5 : g_object_unref (data->object);
907 : 5 : g_free (data);
908 : 5 : }
909 : :
910 : : /*************************************************************
911 : : * Test object notify performance (common code)
912 : : *************************************************************/
913 : :
914 : : #define NUM_NOTIFY_PER_ROUND 10000
915 : :
916 : : struct NotifyTest {
917 : : GObject *object;
918 : : unsigned n_checks;
919 : : };
920 : :
921 : : static void
922 : 112 : test_notify_run (PerformanceTest *test,
923 : : void *_data)
924 : : {
925 : 112 : struct NotifyTest *data = _data;
926 : 112 : GObject *object = data->object;
927 : :
928 [ + + ]: 1152558 : for (unsigned i = 0; i < data->n_checks; i++)
929 : 1152446 : g_object_notify (object, "val1");
930 : 112 : }
931 : :
932 : : static void
933 : 112 : test_notify_by_pspec_run (PerformanceTest *test,
934 : : void *_data)
935 : : {
936 : 112 : struct NotifyTest *data = _data;
937 : 112 : GObject *object = data->object;
938 : :
939 [ + + ]: 1306909 : for (unsigned i = 0; i < data->n_checks; i++)
940 : 1306797 : g_object_notify_by_pspec (object, pspecs[PROP_VAL1]);
941 : 112 : }
942 : :
943 : : /*************************************************************
944 : : * Test notify unhandled performance
945 : : *************************************************************/
946 : :
947 : : static void *
948 : 2 : test_notify_unhandled_setup (PerformanceTest *test)
949 : : {
950 : : struct NotifyTest *data;
951 : :
952 : 2 : data = g_new0 (struct NotifyTest, 1);
953 : 2 : data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
954 : 2 : return data;
955 : : }
956 : :
957 : : static void
958 : 112 : test_notify_unhandled_init (PerformanceTest *test,
959 : : void *_data,
960 : : double factor)
961 : : {
962 : 112 : struct NotifyTest *data = _data;
963 : :
964 : 112 : data->n_checks = factor * NUM_NOTIFY_PER_ROUND;
965 : 112 : }
966 : :
967 : : static void
968 : 112 : test_notify_unhandled_finish (PerformanceTest *test,
969 : : void *data)
970 : : {
971 : 112 : }
972 : :
973 : : static void
974 : 2 : test_notify_unhandled_print_result (PerformanceTest *test,
975 : : void *_data,
976 : : double time)
977 : : {
978 : 2 : struct NotifyTest *data = _data;
979 : :
980 : 2 : g_print ("Notify (unhandled) per second: %.0f\n",
981 : 2 : data->n_checks / time);
982 : 2 : }
983 : :
984 : : static void
985 : 2 : test_notify_unhandled_teardown (PerformanceTest *test,
986 : : void *_data)
987 : : {
988 : 2 : struct NotifyTest *data = _data;
989 : :
990 : 2 : g_object_unref (data->object);
991 : 2 : g_free (data);
992 : 2 : }
993 : :
994 : : /*************************************************************
995 : : * Test notify handled performance
996 : : *************************************************************/
997 : :
998 : : static void
999 : 1109262 : test_notify_handled_handler (ComplexObject *obj, GParamSpec *pspec, void *data)
1000 : : {
1001 : 1109262 : }
1002 : :
1003 : : static void *
1004 : 2 : test_notify_handled_setup (PerformanceTest *test)
1005 : : {
1006 : : struct NotifyTest *data;
1007 : :
1008 : 2 : data = g_new0 (struct NotifyTest, 1);
1009 : 2 : data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
1010 : :
1011 : 2 : g_signal_connect (data->object, "notify::val1",
1012 : : G_CALLBACK (test_notify_handled_handler), data);
1013 : 2 : g_signal_connect (data->object, "notify::val2",
1014 : : G_CALLBACK (test_notify_handled_handler), data);
1015 : :
1016 : 2 : return data;
1017 : : }
1018 : :
1019 : : static void
1020 : 112 : test_notify_handled_init (PerformanceTest *test,
1021 : : void *_data,
1022 : : double factor)
1023 : : {
1024 : 112 : struct NotifyTest *data = _data;
1025 : :
1026 : 112 : data->n_checks = factor * NUM_NOTIFY_PER_ROUND;
1027 : 112 : }
1028 : :
1029 : : static void
1030 : 112 : test_notify_handled_finish (PerformanceTest *test,
1031 : : void *data)
1032 : : {
1033 : 112 : }
1034 : :
1035 : : static void
1036 : 2 : test_notify_handled_print_result (PerformanceTest *test,
1037 : : void *_data,
1038 : : double time)
1039 : : {
1040 : 2 : struct NotifyTest *data = _data;
1041 : :
1042 : 2 : g_print ("Notify per second: %.0f\n",
1043 : 2 : data->n_checks / time);
1044 : 2 : }
1045 : :
1046 : : static void
1047 : 2 : test_notify_handled_teardown (PerformanceTest *test,
1048 : : void *_data)
1049 : : {
1050 : 2 : struct NotifyTest *data = _data;
1051 : :
1052 : 2 : g_assert_cmpuint (
1053 : : g_signal_handlers_disconnect_by_func (data->object,
1054 : : test_notify_handled_handler,
1055 : : data), ==, 2);
1056 : 2 : g_object_unref (data->object);
1057 : 2 : g_free (data);
1058 : 2 : }
1059 : :
1060 : : /*************************************************************
1061 : : * Test object set performance
1062 : : *************************************************************/
1063 : :
1064 : : #define NUM_SET_PER_ROUND 10000
1065 : :
1066 : : struct SetTest {
1067 : : GObject *object;
1068 : : unsigned n_checks;
1069 : : };
1070 : :
1071 : : static void
1072 : 56 : test_set_run (PerformanceTest *test,
1073 : : void *_data)
1074 : : {
1075 : 56 : struct SetTest *data = _data;
1076 : 56 : GObject *object = data->object;
1077 : :
1078 [ + + ]: 579115 : for (unsigned i = 0; i < data->n_checks; i++)
1079 : 579059 : g_object_set (object, "val1", i, NULL);
1080 : 56 : }
1081 : :
1082 : : static void *
1083 : 1 : test_set_setup (PerformanceTest *test)
1084 : : {
1085 : : struct SetTest *data;
1086 : :
1087 : 1 : data = g_new0 (struct SetTest, 1);
1088 : 1 : data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
1089 : :
1090 : 1 : return data;
1091 : : }
1092 : :
1093 : : static void
1094 : 56 : test_set_init (PerformanceTest *test,
1095 : : void *_data,
1096 : : double factor)
1097 : : {
1098 : 56 : struct SetTest *data = _data;
1099 : :
1100 : 56 : data->n_checks = factor * NUM_SET_PER_ROUND;
1101 : 56 : }
1102 : :
1103 : : static void
1104 : 56 : test_set_finish (PerformanceTest *test,
1105 : : void *data)
1106 : : {
1107 : 56 : }
1108 : :
1109 : : static void
1110 : 1 : test_set_print_result (PerformanceTest *test,
1111 : : void *_data,
1112 : : double time)
1113 : : {
1114 : 1 : struct SetTest *data = _data;
1115 : :
1116 : 1 : g_print ("Property set per second: %.0f\n",
1117 : 1 : data->n_checks / time);
1118 : 1 : }
1119 : :
1120 : : static void
1121 : 1 : test_set_teardown (PerformanceTest *test,
1122 : : void *_data)
1123 : : {
1124 : 1 : struct SetTest *data = _data;
1125 : :
1126 : 1 : g_object_unref (data->object);
1127 : 1 : g_free (data);
1128 : 1 : }
1129 : :
1130 : : /*************************************************************
1131 : : * Test object get performance
1132 : : *************************************************************/
1133 : :
1134 : : #define NUM_GET_PER_ROUND 10000
1135 : :
1136 : : struct GetTest {
1137 : : GObject *object;
1138 : : unsigned n_checks;
1139 : : };
1140 : :
1141 : : static void
1142 : 56 : test_get_run (PerformanceTest *test,
1143 : : void *_data)
1144 : : {
1145 : 56 : struct GetTest *data = _data;
1146 : 56 : GObject *object = data->object;
1147 : : int val;
1148 : :
1149 [ + + ]: 579895 : for (unsigned i = 0; i < data->n_checks; i++)
1150 : 579839 : g_object_get (object, "val1", &val, NULL);
1151 : 56 : }
1152 : :
1153 : : static void *
1154 : 1 : test_get_setup (PerformanceTest *test)
1155 : : {
1156 : : struct GetTest *data;
1157 : :
1158 : 1 : data = g_new0 (struct GetTest, 1);
1159 : 1 : data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
1160 : :
1161 : 1 : return data;
1162 : : }
1163 : :
1164 : : static void
1165 : 56 : test_get_init (PerformanceTest *test,
1166 : : void *_data,
1167 : : double factor)
1168 : : {
1169 : 56 : struct GetTest *data = _data;
1170 : :
1171 : 56 : data->n_checks = factor * NUM_GET_PER_ROUND;
1172 : 56 : }
1173 : :
1174 : : static void
1175 : 56 : test_get_finish (PerformanceTest *test,
1176 : : void *data)
1177 : : {
1178 : 56 : }
1179 : :
1180 : : static void
1181 : 1 : test_get_print_result (PerformanceTest *test,
1182 : : void *_data,
1183 : : double time)
1184 : : {
1185 : 1 : struct GetTest *data = _data;
1186 : :
1187 : 1 : g_print ("Property get per second: %.0f\n",
1188 : 1 : data->n_checks / time);
1189 : 1 : }
1190 : :
1191 : : static void
1192 : 1 : test_get_teardown (PerformanceTest *test,
1193 : : gpointer _data)
1194 : : {
1195 : 1 : struct GetTest *data = _data;
1196 : :
1197 : 1 : g_object_unref (data->object);
1198 : 1 : g_free (data);
1199 : 1 : }
1200 : :
1201 : : /*************************************************************
1202 : : * Test object refcount performance
1203 : : *************************************************************/
1204 : :
1205 : : #define NUM_KILO_REFS_PER_ROUND 100000
1206 : :
1207 : : struct RefcountTest {
1208 : : GObject *object;
1209 : : int n_checks;
1210 : : };
1211 : :
1212 : : static gpointer
1213 : 1 : test_refcount_setup (PerformanceTest *test)
1214 : : {
1215 : : struct RefcountTest *data;
1216 : :
1217 : 1 : data = g_new0 (struct RefcountTest, 1);
1218 : 1 : data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
1219 : :
1220 : 1 : return data;
1221 : : }
1222 : :
1223 : : static void
1224 : 56 : test_refcount_init (PerformanceTest *test,
1225 : : gpointer _data,
1226 : : double factor)
1227 : : {
1228 : 56 : struct RefcountTest *data = _data;
1229 : :
1230 : 56 : data->n_checks = factor * NUM_KILO_REFS_PER_ROUND;
1231 : 56 : }
1232 : :
1233 : : static void
1234 : 56 : test_refcount_run (PerformanceTest *test,
1235 : : gpointer _data)
1236 : : {
1237 : 56 : struct RefcountTest *data = _data;
1238 : 56 : GObject *object = data->object;
1239 : : int i;
1240 : :
1241 [ + + ]: 5530840 : for (i = 0; i < data->n_checks; i++)
1242 : : {
1243 : 5530784 : g_object_ref (object);
1244 : 5530784 : g_object_ref (object);
1245 : 5530784 : g_object_ref (object);
1246 : 5530784 : g_object_unref (object);
1247 : 5530784 : g_object_unref (object);
1248 : :
1249 : 5530784 : g_object_ref (object);
1250 : 5530784 : g_object_ref (object);
1251 : 5530784 : g_object_unref (object);
1252 : 5530784 : g_object_unref (object);
1253 : 5530784 : g_object_unref (object);
1254 : : }
1255 : 56 : }
1256 : :
1257 : : static void
1258 : 56 : test_refcount_finish (PerformanceTest *test,
1259 : : gpointer _data)
1260 : : {
1261 : 56 : }
1262 : :
1263 : : static void
1264 : 1 : test_refcount_print_result (PerformanceTest *test,
1265 : : gpointer _data,
1266 : : double time)
1267 : : {
1268 : 1 : struct RefcountTest *data = _data;
1269 : 1 : g_print ("Million refs+unref per second: %.2f\n",
1270 : 1 : data->n_checks * 5 / (time * 1000000 ));
1271 : 1 : }
1272 : :
1273 : : static void
1274 : 1 : test_refcount_teardown (PerformanceTest *test,
1275 : : gpointer _data)
1276 : : {
1277 : 1 : struct RefcountTest *data = _data;
1278 : :
1279 : 1 : g_object_unref (data->object);
1280 : 1 : g_free (data);
1281 : 1 : }
1282 : :
1283 : : /*************************************************************
1284 : : * Main test code
1285 : : *************************************************************/
1286 : :
1287 : : static PerformanceTest tests[] = {
1288 : : {
1289 : : "simple-construction",
1290 : : simple_object_get_type,
1291 : : test_construction_setup,
1292 : : test_construction_init,
1293 : : test_construction_run,
1294 : : test_construction_finish,
1295 : : test_construction_teardown,
1296 : : test_construction_print_result
1297 : : },
1298 : : {
1299 : : "simple-construction1",
1300 : : simple_object_get_type,
1301 : : test_construction_setup,
1302 : : test_construction_init,
1303 : : test_construction_run1,
1304 : : test_construction_finish1,
1305 : : test_construction_teardown,
1306 : : test_construction_print_result
1307 : : },
1308 : : {
1309 : : "complex-construction",
1310 : : complex_object_get_type,
1311 : : test_construction_setup,
1312 : : test_construction_init,
1313 : : test_complex_construction_run,
1314 : : test_construction_finish,
1315 : : test_construction_teardown,
1316 : : test_construction_print_result
1317 : : },
1318 : : {
1319 : : "complex-construction1",
1320 : : complex_object_get_type,
1321 : : test_construction_setup,
1322 : : test_construction_init,
1323 : : test_complex_construction_run1,
1324 : : test_construction_finish,
1325 : : test_construction_teardown,
1326 : : test_construction_print_result
1327 : : },
1328 : : {
1329 : : "complex-construction2",
1330 : : complex_object_get_type,
1331 : : test_construction_setup,
1332 : : test_construction_init,
1333 : : test_complex_construction_run2,
1334 : : test_construction_finish,
1335 : : test_construction_teardown,
1336 : : test_construction_print_result
1337 : : },
1338 : : {
1339 : : "finalization",
1340 : : simple_object_get_type,
1341 : : test_construction_setup,
1342 : : test_finalization_init,
1343 : : test_finalization_run,
1344 : : test_finalization_finish,
1345 : : test_construction_teardown,
1346 : : test_finalization_print_result
1347 : : },
1348 : : {
1349 : : "type-check",
1350 : : NULL,
1351 : : test_type_check_setup,
1352 : : test_type_check_init,
1353 : : test_type_check_run,
1354 : : test_type_check_finish,
1355 : : test_type_check_teardown,
1356 : : test_type_check_print_result
1357 : : },
1358 : : {
1359 : : "emit-unhandled",
1360 : : GINT_TO_POINTER (COMPLEX_SIGNAL),
1361 : : test_emission_unhandled_setup,
1362 : : test_emission_unhandled_init,
1363 : : test_emission_run,
1364 : : test_emission_unhandled_finish,
1365 : : test_emission_unhandled_teardown,
1366 : : test_emission_unhandled_print_result
1367 : : },
1368 : : {
1369 : : "emit-unhandled-empty",
1370 : : GINT_TO_POINTER (COMPLEX_SIGNAL_EMPTY),
1371 : : test_emission_unhandled_setup,
1372 : : test_emission_unhandled_init,
1373 : : test_emission_run,
1374 : : test_emission_unhandled_finish,
1375 : : test_emission_unhandled_teardown,
1376 : : test_emission_unhandled_print_result
1377 : : },
1378 : : {
1379 : : "emit-unhandled-generic",
1380 : : GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC),
1381 : : test_emission_unhandled_setup,
1382 : : test_emission_unhandled_init,
1383 : : test_emission_run,
1384 : : test_emission_unhandled_finish,
1385 : : test_emission_unhandled_teardown,
1386 : : test_emission_unhandled_print_result
1387 : : },
1388 : : {
1389 : : "emit-unhandled-generic-empty",
1390 : : GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC_EMPTY),
1391 : : test_emission_unhandled_setup,
1392 : : test_emission_unhandled_init,
1393 : : test_emission_run,
1394 : : test_emission_unhandled_finish,
1395 : : test_emission_unhandled_teardown,
1396 : : test_emission_unhandled_print_result
1397 : : },
1398 : : {
1399 : : "emit-unhandled-args",
1400 : : GINT_TO_POINTER (COMPLEX_SIGNAL_ARGS),
1401 : : test_emission_unhandled_setup,
1402 : : test_emission_unhandled_init,
1403 : : test_emission_run_args,
1404 : : test_emission_unhandled_finish,
1405 : : test_emission_unhandled_teardown,
1406 : : test_emission_unhandled_print_result
1407 : : },
1408 : : {
1409 : : "emit-handled",
1410 : : GINT_TO_POINTER (COMPLEX_SIGNAL),
1411 : : test_emission_handled_setup,
1412 : : test_emission_handled_init,
1413 : : test_emission_run,
1414 : : test_emission_handled_finish,
1415 : : test_emission_handled_teardown,
1416 : : test_emission_handled_print_result
1417 : : },
1418 : : {
1419 : : "emit-handled-empty",
1420 : : GINT_TO_POINTER (COMPLEX_SIGNAL_EMPTY),
1421 : : test_emission_handled_setup,
1422 : : test_emission_handled_init,
1423 : : test_emission_run,
1424 : : test_emission_handled_finish,
1425 : : test_emission_handled_teardown,
1426 : : test_emission_handled_print_result
1427 : : },
1428 : : {
1429 : : "emit-handled-generic",
1430 : : GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC),
1431 : : test_emission_handled_setup,
1432 : : test_emission_handled_init,
1433 : : test_emission_run,
1434 : : test_emission_handled_finish,
1435 : : test_emission_handled_teardown,
1436 : : test_emission_handled_print_result
1437 : : },
1438 : : {
1439 : : "emit-handled-generic-empty",
1440 : : GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC_EMPTY),
1441 : : test_emission_handled_setup,
1442 : : test_emission_handled_init,
1443 : : test_emission_run,
1444 : : test_emission_handled_finish,
1445 : : test_emission_handled_teardown,
1446 : : test_emission_handled_print_result
1447 : : },
1448 : : {
1449 : : "emit-handled-args",
1450 : : GINT_TO_POINTER (COMPLEX_SIGNAL_ARGS),
1451 : : test_emission_handled_setup,
1452 : : test_emission_handled_init,
1453 : : test_emission_run_args,
1454 : : test_emission_handled_finish,
1455 : : test_emission_handled_teardown,
1456 : : test_emission_handled_print_result
1457 : : },
1458 : : {
1459 : : "notify-unhandled",
1460 : : complex_object_get_type,
1461 : : test_notify_unhandled_setup,
1462 : : test_notify_unhandled_init,
1463 : : test_notify_run,
1464 : : test_notify_unhandled_finish,
1465 : : test_notify_unhandled_teardown,
1466 : : test_notify_unhandled_print_result
1467 : : },
1468 : : {
1469 : : "notify-by-pspec-unhandled",
1470 : : complex_object_get_type,
1471 : : test_notify_unhandled_setup,
1472 : : test_notify_unhandled_init,
1473 : : test_notify_by_pspec_run,
1474 : : test_notify_unhandled_finish,
1475 : : test_notify_unhandled_teardown,
1476 : : test_notify_unhandled_print_result
1477 : : },
1478 : : {
1479 : : "notify-handled",
1480 : : complex_object_get_type,
1481 : : test_notify_handled_setup,
1482 : : test_notify_handled_init,
1483 : : test_notify_run,
1484 : : test_notify_handled_finish,
1485 : : test_notify_handled_teardown,
1486 : : test_notify_handled_print_result
1487 : : },
1488 : : {
1489 : : "notify-by-pspec-handled",
1490 : : complex_object_get_type,
1491 : : test_notify_handled_setup,
1492 : : test_notify_handled_init,
1493 : : test_notify_by_pspec_run,
1494 : : test_notify_handled_finish,
1495 : : test_notify_handled_teardown,
1496 : : test_notify_handled_print_result
1497 : : },
1498 : : {
1499 : : "property-set",
1500 : : complex_object_get_type,
1501 : : test_set_setup,
1502 : : test_set_init,
1503 : : test_set_run,
1504 : : test_set_finish,
1505 : : test_set_teardown,
1506 : : test_set_print_result
1507 : : },
1508 : : {
1509 : : "property-get",
1510 : : complex_object_get_type,
1511 : : test_get_setup,
1512 : : test_get_init,
1513 : : test_get_run,
1514 : : test_get_finish,
1515 : : test_get_teardown,
1516 : : test_get_print_result
1517 : : },
1518 : : {
1519 : : "refcount",
1520 : : NULL,
1521 : : test_refcount_setup,
1522 : : test_refcount_init,
1523 : : test_refcount_run,
1524 : : test_refcount_finish,
1525 : : test_refcount_teardown,
1526 : : test_refcount_print_result
1527 : : }
1528 : : };
1529 : :
1530 : : static PerformanceTest *
1531 : 0 : find_test (const char *name)
1532 : : {
1533 : : gsize i;
1534 [ # # ]: 0 : for (i = 0; i < G_N_ELEMENTS (tests); i++)
1535 : : {
1536 [ # # ]: 0 : if (strcmp (tests[i].name, name) == 0)
1537 : 0 : return &tests[i];
1538 : : }
1539 : 0 : return NULL;
1540 : : }
1541 : : int
1542 : 1 : main (int argc,
1543 : : char *argv[])
1544 : : {
1545 : : PerformanceTest *test;
1546 : : GOptionContext *context;
1547 : 1 : GError *error = NULL;
1548 : : int i;
1549 : :
1550 : 1 : context = g_option_context_new ("GObject performance tests");
1551 : 1 : g_option_context_add_main_entries (context, cmd_entries, NULL);
1552 [ - + ]: 1 : if (!g_option_context_parse (context, &argc, &argv, &error))
1553 : : {
1554 : 0 : g_printerr ("%s: %s\n", argv[0], error->message);
1555 : 0 : return 1;
1556 : : }
1557 : :
1558 [ - + ]: 1 : if (argc > 1)
1559 : : {
1560 [ # # ]: 0 : for (i = 1; i < argc; i++)
1561 : : {
1562 : 0 : test = find_test (argv[i]);
1563 [ # # ]: 0 : if (test)
1564 : 0 : run_test (test);
1565 : : }
1566 : : }
1567 : : else
1568 : : {
1569 : : gsize k;
1570 [ + + ]: 25 : for (k = 0; k < G_N_ELEMENTS (tests); k++)
1571 : 24 : run_test (&tests[k]);
1572 : : }
1573 : :
1574 : 1 : g_option_context_free (context);
1575 : 1 : return 0;
1576 : : }
|