gobject: Use fast fundamental instance type check
[glib.git] / tests / gobject / performance.c
blobe4cb736a03df72c3f5d77adcacda02b343c1478b
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 WARM_UP_N_RUNS 50
24 #define ESTIMATE_ROUND_TIME_N_RUNS 5
25 #define DEFAULT_TEST_TIME 15 /* seconds */
26 /* The time we want each round to take, in seconds, this should
27 * be large enough compared to the timer resolution, but small
28 * enought that the risk of any random slowness will miss the
29 * running window */
30 #define TARGET_ROUND_TIME 0.004
32 static gboolean verbose = FALSE;
33 static int test_length = DEFAULT_TEST_TIME;
35 static GOptionEntry cmd_entries[] = {
36 {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
37 "Print extra information", NULL},
38 {"seconds", 's', 0, G_OPTION_ARG_INT, &test_length,
39 "Time to run each test in seconds", NULL},
40 {NULL}
43 typedef struct _PerformanceTest PerformanceTest;
44 struct _PerformanceTest {
45 const char *name;
46 gpointer extra_data;
48 gpointer (*setup) (PerformanceTest *test);
49 void (*init) (PerformanceTest *test,
50 gpointer data,
51 double factor);
52 void (*run) (PerformanceTest *test,
53 gpointer data);
54 void (*finish) (PerformanceTest *test,
55 gpointer data);
56 void (*teardown) (PerformanceTest *test,
57 gpointer data);
58 void (*print_result) (PerformanceTest *test,
59 gpointer data,
60 double time);
63 static void
64 run_test (PerformanceTest *test)
66 gpointer data = NULL;
67 guint64 i, num_rounds;
68 double elapsed, min_elapsed, factor;
69 GTimer *timer;
71 g_print ("Running test %s\n", test->name);
73 /* Set up test */
74 timer = g_timer_new ();
75 data = test->setup (test);
77 if (verbose)
78 g_print ("Warming up\n");
80 /* Warm up the test by doing a few runs */
81 for (i = 0; i < WARM_UP_N_RUNS; i++)
83 test->init (test, data, 1.0);
84 test->run (test, data);
85 test->finish (test, data);
88 if (verbose)
89 g_print ("Estimating round time\n");
91 /* Estimate time for one run by doing a few test rounds */
92 min_elapsed = 0;
93 for (i = 0; i < ESTIMATE_ROUND_TIME_N_RUNS; i++)
95 test->init (test, data, 1.0);
96 g_timer_start (timer);
97 test->run (test, data);
98 g_timer_stop (timer);
99 test->finish (test, data);
101 elapsed = g_timer_elapsed (timer, NULL);
102 if (i == 0)
103 min_elapsed = elapsed;
104 else
105 min_elapsed = MIN (min_elapsed, elapsed);
108 factor = TARGET_ROUND_TIME / min_elapsed;
110 if (verbose)
111 g_print ("Uncorrected round time: %f.4 secs, correction factor %f.2\n", min_elapsed, factor);
113 /* Calculate number of rounds needed */
114 num_rounds = (test_length / TARGET_ROUND_TIME) + 1;
116 if (verbose)
117 g_print ("Running %"G_GINT64_MODIFIER"d rounds\n", num_rounds);
119 /* Run the test */
120 for (i = 0; i < num_rounds; i++)
122 test->init (test, data, factor);
123 g_timer_start (timer);
124 test->run (test, data);
125 g_timer_stop (timer);
126 test->finish (test, data);
127 elapsed = g_timer_elapsed (timer, NULL);
129 if (i == 0)
130 min_elapsed = elapsed;
131 else
132 min_elapsed = MIN (min_elapsed, elapsed);
135 if (verbose)
136 g_print ("Minimum corrected round time: %f secs\n", min_elapsed);
138 /* Print the results */
139 test->print_result (test, data, min_elapsed);
141 /* Tear down */
142 test->teardown (test, data);
143 g_timer_destroy (timer);
146 /*************************************************************
147 * Simple object is a very simple small GObject subclass
148 * with no properties, no signals, implementing no interfaces
149 *************************************************************/
151 static GType simple_object_get_type (void);
152 #define SIMPLE_TYPE_OBJECT (simple_object_get_type ())
153 typedef struct _SimpleObject SimpleObject;
154 typedef struct _SimpleObjectClass SimpleObjectClass;
156 struct _SimpleObject
158 GObject parent_instance;
159 int val;
162 struct _SimpleObjectClass
164 GObjectClass parent_class;
167 G_DEFINE_TYPE (SimpleObject, simple_object, G_TYPE_OBJECT);
169 static void
170 simple_object_finalize (GObject *object)
172 G_OBJECT_CLASS (simple_object_parent_class)->finalize (object);
175 static void
176 simple_object_class_init (SimpleObjectClass *class)
178 GObjectClass *object_class = G_OBJECT_CLASS (class);
180 object_class->finalize = simple_object_finalize;
183 static void
184 simple_object_init (SimpleObject *simple_object)
186 simple_object->val = 42;
189 typedef struct _TestIfaceClass TestIfaceClass;
190 typedef struct _TestIfaceClass TestIface1Class;
191 typedef struct _TestIfaceClass TestIface2Class;
192 typedef struct _TestIfaceClass TestIface3Class;
193 typedef struct _TestIfaceClass TestIface4Class;
194 typedef struct _TestIfaceClass TestIface5Class;
195 typedef struct _TestIface TestIface;
197 struct _TestIfaceClass
199 GTypeInterface base_iface;
200 void (*method) (TestIface *obj);
203 static GType test_iface1_get_type (void);
204 static GType test_iface2_get_type (void);
205 static GType test_iface3_get_type (void);
206 static GType test_iface4_get_type (void);
207 static GType test_iface5_get_type (void);
209 #define TEST_TYPE_IFACE1 (test_iface1_get_type ())
210 #define TEST_TYPE_IFACE2 (test_iface2_get_type ())
211 #define TEST_TYPE_IFACE3 (test_iface3_get_type ())
212 #define TEST_TYPE_IFACE4 (test_iface4_get_type ())
213 #define TEST_TYPE_IFACE5 (test_iface5_get_type ())
215 static DEFINE_IFACE (TestIface1, test_iface1, NULL, NULL)
216 static DEFINE_IFACE (TestIface2, test_iface2, NULL, NULL)
217 static DEFINE_IFACE (TestIface3, test_iface3, NULL, NULL)
218 static DEFINE_IFACE (TestIface4, test_iface4, NULL, NULL)
219 static DEFINE_IFACE (TestIface5, test_iface5, NULL, NULL)
221 /*************************************************************
222 * Complex object is a GObject subclass with a properties,
223 * construct properties, signals and implementing an interface.
224 *************************************************************/
226 static GType complex_object_get_type (void);
227 #define COMPLEX_TYPE_OBJECT (complex_object_get_type ())
228 typedef struct _ComplexObject ComplexObject;
229 typedef struct _ComplexObjectClass ComplexObjectClass;
231 struct _ComplexObject
233 GObject parent_instance;
234 int val1;
235 int val2;
238 struct _ComplexObjectClass
240 GObjectClass parent_class;
242 void (*signal) (ComplexObject *obj);
243 void (*signal_empty) (ComplexObject *obj);
246 static void complex_test_iface_init (gpointer g_iface,
247 gpointer iface_data);
249 G_DEFINE_TYPE_EXTENDED (ComplexObject, complex_object,
250 G_TYPE_OBJECT, 0,
251 G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE1,
252 complex_test_iface_init)
253 G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE2,
254 complex_test_iface_init)
255 G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE3,
256 complex_test_iface_init)
257 G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE4,
258 complex_test_iface_init)
259 G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE5,
260 complex_test_iface_init)
263 #define COMPLEX_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), COMPLEX_TYPE_OBJECT, ComplexObject))
265 enum {
266 PROP_0,
267 PROP_VAL1,
268 PROP_VAL2
271 enum {
272 COMPLEX_SIGNAL,
273 COMPLEX_SIGNAL_EMPTY,
274 COMPLEX_SIGNAL_GENERIC,
275 COMPLEX_SIGNAL_GENERIC_EMPTY,
276 COMPLEX_SIGNAL_ARGS,
277 COMPLEX_LAST_SIGNAL
280 static guint complex_signals[COMPLEX_LAST_SIGNAL] = { 0 };
282 static void
283 complex_object_finalize (GObject *object)
285 G_OBJECT_CLASS (complex_object_parent_class)->finalize (object);
288 static void
289 complex_object_set_property (GObject *object,
290 guint prop_id,
291 const GValue *value,
292 GParamSpec *pspec)
294 ComplexObject *complex = COMPLEX_OBJECT (object);
296 switch (prop_id)
298 case PROP_VAL1:
299 complex->val1 = g_value_get_int (value);
300 break;
301 case PROP_VAL2:
302 complex->val2 = g_value_get_int (value);
303 break;
304 default:
305 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
306 break;
310 static void
311 complex_object_get_property (GObject *object,
312 guint prop_id,
313 GValue *value,
314 GParamSpec *pspec)
316 ComplexObject *complex = COMPLEX_OBJECT (object);
318 switch (prop_id)
320 case PROP_VAL1:
321 g_value_set_int (value, complex->val1);
322 break;
323 case PROP_VAL2:
324 g_value_set_int (value, complex->val2);
325 break;
326 default:
327 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
328 break;
332 static void
333 complex_object_real_signal (ComplexObject *obj)
337 static void
338 complex_object_class_init (ComplexObjectClass *class)
340 GObjectClass *object_class = G_OBJECT_CLASS (class);
342 object_class->finalize = complex_object_finalize;
343 object_class->set_property = complex_object_set_property;
344 object_class->get_property = complex_object_get_property;
346 class->signal = complex_object_real_signal;
348 complex_signals[COMPLEX_SIGNAL] =
349 g_signal_new ("signal",
350 G_TYPE_FROM_CLASS (object_class),
351 G_SIGNAL_RUN_FIRST,
352 G_STRUCT_OFFSET (ComplexObjectClass, signal),
353 NULL, NULL,
354 g_cclosure_marshal_VOID__VOID,
355 G_TYPE_NONE, 0);
357 complex_signals[COMPLEX_SIGNAL_EMPTY] =
358 g_signal_new ("signal-empty",
359 G_TYPE_FROM_CLASS (object_class),
360 G_SIGNAL_RUN_FIRST,
361 G_STRUCT_OFFSET (ComplexObjectClass, signal_empty),
362 NULL, NULL,
363 g_cclosure_marshal_VOID__VOID,
364 G_TYPE_NONE, 0);
366 complex_signals[COMPLEX_SIGNAL_GENERIC] =
367 g_signal_new ("signal-generic",
368 G_TYPE_FROM_CLASS (object_class),
369 G_SIGNAL_RUN_FIRST,
370 G_STRUCT_OFFSET (ComplexObjectClass, signal),
371 NULL, NULL,
372 NULL,
373 G_TYPE_NONE, 0);
374 complex_signals[COMPLEX_SIGNAL_GENERIC_EMPTY] =
375 g_signal_new ("signal-generic-empty",
376 G_TYPE_FROM_CLASS (object_class),
377 G_SIGNAL_RUN_FIRST,
378 G_STRUCT_OFFSET (ComplexObjectClass, signal_empty),
379 NULL, NULL,
380 NULL,
381 G_TYPE_NONE, 0);
383 complex_signals[COMPLEX_SIGNAL_ARGS] =
384 g_signal_new ("signal-args",
385 G_TYPE_FROM_CLASS (object_class),
386 G_SIGNAL_RUN_FIRST,
387 G_STRUCT_OFFSET (ComplexObjectClass, signal),
388 NULL, NULL,
389 g_cclosure_marshal_VOID__UINT_POINTER,
390 G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER);
392 g_object_class_install_property (object_class,
393 PROP_VAL1,
394 g_param_spec_int ("val1",
395 "val1",
396 "val1",
398 G_MAXINT,
400 G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
401 g_object_class_install_property (object_class,
402 PROP_VAL2,
403 g_param_spec_int ("val2",
404 "val2",
405 "val2",
407 G_MAXINT,
409 G_PARAM_READWRITE));
414 static void
415 complex_object_iface_method (TestIface *obj)
417 ComplexObject *complex = COMPLEX_OBJECT (obj);
418 complex->val1++;
421 static void
422 complex_test_iface_init (gpointer g_iface,
423 gpointer iface_data)
425 TestIfaceClass *iface = g_iface;
426 iface->method = complex_object_iface_method;
429 static void
430 complex_object_init (ComplexObject *complex_object)
432 complex_object->val2 = 43;
435 /*************************************************************
436 * Test object construction performance
437 *************************************************************/
439 #define NUM_OBJECT_TO_CONSTRUCT 10000
441 struct ConstructionTest {
442 GObject **objects;
443 int n_objects;
444 GType type;
447 static gpointer
448 test_construction_setup (PerformanceTest *test)
450 struct ConstructionTest *data;
452 data = g_new0 (struct ConstructionTest, 1);
453 data->type = ((GType (*)(void))test->extra_data)();
455 return data;
458 static void
459 test_construction_init (PerformanceTest *test,
460 gpointer _data,
461 double count_factor)
463 struct ConstructionTest *data = _data;
464 int n;
466 n = NUM_OBJECT_TO_CONSTRUCT * count_factor;
467 if (data->n_objects != n)
469 data->n_objects = n;
470 data->objects = g_new (GObject *, n);
474 static void
475 test_construction_run (PerformanceTest *test,
476 gpointer _data)
478 struct ConstructionTest *data = _data;
479 GObject **objects = data->objects;
480 GType type = data->type;
481 int i, n_objects;
483 n_objects = data->n_objects;
484 for (i = 0; i < n_objects; i++)
485 objects[i] = g_object_new (type, NULL);
488 static void
489 test_construction_finish (PerformanceTest *test,
490 gpointer _data)
492 struct ConstructionTest *data = _data;
493 int i;
495 for (i = 0; i < data->n_objects; i++)
496 g_object_unref (data->objects[i]);
499 static void
500 test_construction_teardown (PerformanceTest *test,
501 gpointer _data)
503 struct ConstructionTest *data = _data;
504 g_free (data->objects);
505 g_free (data);
508 static void
509 test_construction_print_result (PerformanceTest *test,
510 gpointer _data,
511 double time)
513 struct ConstructionTest *data = _data;
515 g_print ("Number of constructed objects per second: %.0f\n",
516 data->n_objects / time);
519 /*************************************************************
520 * Test runtime type check performance
521 *************************************************************/
523 #define NUM_KILO_CHECKS_PER_ROUND 50
525 struct TypeCheckTest {
526 GObject *object;
527 int n_checks;
530 static gpointer
531 test_type_check_setup (PerformanceTest *test)
533 struct TypeCheckTest *data;
535 data = g_new0 (struct TypeCheckTest, 1);
536 data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
538 return data;
541 static void
542 test_type_check_init (PerformanceTest *test,
543 gpointer _data,
544 double factor)
546 struct TypeCheckTest *data = _data;
548 data->n_checks = factor * NUM_KILO_CHECKS_PER_ROUND;
552 /* Work around g_type_check_instance_is_a being marked "pure",
553 and thus only called once for the loop. */
554 gboolean (*my_type_check_instance_is_a) (GTypeInstance *type_instance,
555 GType iface_type) = &g_type_check_instance_is_a;
557 static void
558 test_type_check_run (PerformanceTest *test,
559 gpointer _data)
561 struct TypeCheckTest *data = _data;
562 volatile GObject *object = data->object;
563 volatile GType type, types[5];
564 int i, j;
566 types[0] = test_iface1_get_type ();
567 types[1] = test_iface2_get_type ();
568 types[2] = test_iface3_get_type ();
569 types[3] = test_iface4_get_type ();
570 types[4] = test_iface5_get_type ();
572 for (i = 0; i < data->n_checks; i++)
574 type = types[i%5];
575 for (j = 0; j < 1000; j++)
577 my_type_check_instance_is_a ((GTypeInstance *)object,
578 type);
583 static void
584 test_type_check_finish (PerformanceTest *test,
585 gpointer data)
589 static void
590 test_type_check_print_result (PerformanceTest *test,
591 gpointer _data,
592 double time)
594 struct TypeCheckTest *data = _data;
595 g_print ("Million type checks per second: %.2f\n",
596 data->n_checks / (1000*time));
599 static void
600 test_type_check_teardown (PerformanceTest *test,
601 gpointer _data)
603 struct TypeCheckTest *data = _data;
605 g_object_unref (data->object);
606 g_free (data);
609 /*************************************************************
610 * Test signal emissions performance (common code)
611 *************************************************************/
613 #define NUM_EMISSIONS_PER_ROUND 10000
615 struct EmissionTest {
616 GObject *object;
617 int n_checks;
618 int signal_id;
621 static void
622 test_emission_run (PerformanceTest *test,
623 gpointer _data)
625 struct EmissionTest *data = _data;
626 GObject *object = data->object;
627 int i;
629 for (i = 0; i < data->n_checks; i++)
630 g_signal_emit (object, data->signal_id, 0);
633 static void
634 test_emission_run_args (PerformanceTest *test,
635 gpointer _data)
637 struct EmissionTest *data = _data;
638 GObject *object = data->object;
639 int i;
641 for (i = 0; i < data->n_checks; i++)
642 g_signal_emit (object, data->signal_id, 0, 0, NULL);
645 /*************************************************************
646 * Test signal unhandled emissions performance
647 *************************************************************/
649 static gpointer
650 test_emission_unhandled_setup (PerformanceTest *test)
652 struct EmissionTest *data;
654 data = g_new0 (struct EmissionTest, 1);
655 data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
656 data->signal_id = complex_signals[GPOINTER_TO_INT (test->extra_data)];
657 return data;
660 static void
661 test_emission_unhandled_init (PerformanceTest *test,
662 gpointer _data,
663 double factor)
665 struct EmissionTest *data = _data;
667 data->n_checks = factor * NUM_EMISSIONS_PER_ROUND;
670 static void
671 test_emission_unhandled_finish (PerformanceTest *test,
672 gpointer data)
676 static void
677 test_emission_unhandled_print_result (PerformanceTest *test,
678 gpointer _data,
679 double time)
681 struct EmissionTest *data = _data;
683 g_print ("Emissions per second: %.0f\n",
684 data->n_checks / time);
687 static void
688 test_emission_unhandled_teardown (PerformanceTest *test,
689 gpointer _data)
691 struct EmissionTest *data = _data;
693 g_object_unref (data->object);
694 g_free (data);
697 /*************************************************************
698 * Test signal handled emissions performance
699 *************************************************************/
701 static void
702 test_emission_handled_handler (ComplexObject *obj, gpointer data)
706 static gpointer
707 test_emission_handled_setup (PerformanceTest *test)
709 struct EmissionTest *data;
711 data = g_new0 (struct EmissionTest, 1);
712 data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
713 data->signal_id = complex_signals[GPOINTER_TO_INT (test->extra_data)];
714 g_signal_connect (data->object, "signal",
715 G_CALLBACK (test_emission_handled_handler),
716 NULL);
717 g_signal_connect (data->object, "signal-empty",
718 G_CALLBACK (test_emission_handled_handler),
719 NULL);
720 g_signal_connect (data->object, "signal-generic",
721 G_CALLBACK (test_emission_handled_handler),
722 NULL);
723 g_signal_connect (data->object, "signal-generic-empty",
724 G_CALLBACK (test_emission_handled_handler),
725 NULL);
726 g_signal_connect (data->object, "signal-args",
727 G_CALLBACK (test_emission_handled_handler),
728 NULL);
730 return data;
733 static void
734 test_emission_handled_init (PerformanceTest *test,
735 gpointer _data,
736 double factor)
738 struct EmissionTest *data = _data;
740 data->n_checks = factor * NUM_EMISSIONS_PER_ROUND;
743 static void
744 test_emission_handled_finish (PerformanceTest *test,
745 gpointer data)
749 static void
750 test_emission_handled_print_result (PerformanceTest *test,
751 gpointer _data,
752 double time)
754 struct EmissionTest *data = _data;
756 g_print ("Emissions per second: %.0f\n",
757 data->n_checks / time);
760 static void
761 test_emission_handled_teardown (PerformanceTest *test,
762 gpointer _data)
764 struct EmissionTest *data = _data;
766 g_object_unref (data->object);
767 g_free (data);
770 /*************************************************************
771 * Main test code
772 *************************************************************/
774 static PerformanceTest tests[] = {
776 "simple-construction",
777 simple_object_get_type,
778 test_construction_setup,
779 test_construction_init,
780 test_construction_run,
781 test_construction_finish,
782 test_construction_teardown,
783 test_construction_print_result
786 "complex-construction",
787 complex_object_get_type,
788 test_construction_setup,
789 test_construction_init,
790 test_construction_run,
791 test_construction_finish,
792 test_construction_teardown,
793 test_construction_print_result
796 "type-check",
797 NULL,
798 test_type_check_setup,
799 test_type_check_init,
800 test_type_check_run,
801 test_type_check_finish,
802 test_type_check_teardown,
803 test_type_check_print_result
806 "emit-unhandled",
807 GINT_TO_POINTER (COMPLEX_SIGNAL),
808 test_emission_unhandled_setup,
809 test_emission_unhandled_init,
810 test_emission_run,
811 test_emission_unhandled_finish,
812 test_emission_unhandled_teardown,
813 test_emission_unhandled_print_result
816 "emit-unhandled-empty",
817 GINT_TO_POINTER (COMPLEX_SIGNAL_EMPTY),
818 test_emission_unhandled_setup,
819 test_emission_unhandled_init,
820 test_emission_run,
821 test_emission_unhandled_finish,
822 test_emission_unhandled_teardown,
823 test_emission_unhandled_print_result
826 "emit-unhandled-generic",
827 GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC),
828 test_emission_unhandled_setup,
829 test_emission_unhandled_init,
830 test_emission_run,
831 test_emission_unhandled_finish,
832 test_emission_unhandled_teardown,
833 test_emission_unhandled_print_result
836 "emit-unhandled-generic-empty",
837 GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC_EMPTY),
838 test_emission_unhandled_setup,
839 test_emission_unhandled_init,
840 test_emission_run,
841 test_emission_unhandled_finish,
842 test_emission_unhandled_teardown,
843 test_emission_unhandled_print_result
846 "emit-unhandled-args",
847 GINT_TO_POINTER (COMPLEX_SIGNAL_ARGS),
848 test_emission_unhandled_setup,
849 test_emission_unhandled_init,
850 test_emission_run_args,
851 test_emission_unhandled_finish,
852 test_emission_unhandled_teardown,
853 test_emission_unhandled_print_result
856 "emit-handled",
857 GINT_TO_POINTER (COMPLEX_SIGNAL),
858 test_emission_handled_setup,
859 test_emission_handled_init,
860 test_emission_run,
861 test_emission_handled_finish,
862 test_emission_handled_teardown,
863 test_emission_handled_print_result
866 "emit-handled-empty",
867 GINT_TO_POINTER (COMPLEX_SIGNAL_EMPTY),
868 test_emission_handled_setup,
869 test_emission_handled_init,
870 test_emission_run,
871 test_emission_handled_finish,
872 test_emission_handled_teardown,
873 test_emission_handled_print_result
876 "emit-handled-generic",
877 GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC),
878 test_emission_handled_setup,
879 test_emission_handled_init,
880 test_emission_run,
881 test_emission_handled_finish,
882 test_emission_handled_teardown,
883 test_emission_handled_print_result
886 "emit-handled-generic-empty",
887 GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC_EMPTY),
888 test_emission_handled_setup,
889 test_emission_handled_init,
890 test_emission_run,
891 test_emission_handled_finish,
892 test_emission_handled_teardown,
893 test_emission_handled_print_result
896 "emit-handled-args",
897 GINT_TO_POINTER (COMPLEX_SIGNAL_ARGS),
898 test_emission_handled_setup,
899 test_emission_handled_init,
900 test_emission_run_args,
901 test_emission_handled_finish,
902 test_emission_handled_teardown,
903 test_emission_handled_print_result
907 static PerformanceTest *
908 find_test (const char *name)
910 int i;
911 for (i = 0; i < G_N_ELEMENTS (tests); i++)
913 if (strcmp (tests[i].name, name) == 0)
914 return &tests[i];
916 return NULL;
919 main (int argc,
920 char *argv[])
922 PerformanceTest *test;
923 GOptionContext *context;
924 GError *error = NULL;
925 int i;
927 context = g_option_context_new ("GObject performance tests");
928 g_option_context_add_main_entries (context, cmd_entries, NULL);
929 if (!g_option_context_parse (context, &argc, &argv, &error))
931 g_printerr ("%s: %s\n", argv[0], error->message);
932 return 1;
935 if (argc > 1)
937 for (i = 1; i < argc; i++)
939 test = find_test (argv[i]);
940 if (test)
941 run_test (test);
944 else
946 for (i = 0; i < G_N_ELEMENTS (tests); i++)
947 run_test (&tests[i]);
950 return 0;