glib/tests/gobject/performance.c

1055 lines
26 KiB
C
Raw Normal View History

Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 2009 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
2014-01-23 12:58:29 +01:00
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
*/
#include <math.h>
#include <string.h>
#include <glib-object.h>
#include "testcommon.h"
#define WARM_UP_N_RUNS 50
#define ESTIMATE_ROUND_TIME_N_RUNS 5
#define DEFAULT_TEST_TIME 15 /* seconds */
/* The time we want each round to take, in seconds, this should
* be large enough compared to the timer resolution, but small
* enought that the risk of any random slowness will miss the
* running window */
#define TARGET_ROUND_TIME 0.008
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
static gboolean verbose = FALSE;
static int test_length = DEFAULT_TEST_TIME;
static GOptionEntry cmd_entries[] = {
{"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
"Print extra information", NULL},
{"seconds", 's', 0, G_OPTION_ARG_INT, &test_length,
"Time to run each test in seconds", NULL},
{NULL}
};
typedef struct _PerformanceTest PerformanceTest;
struct _PerformanceTest {
const char *name;
gpointer extra_data;
gpointer (*setup) (PerformanceTest *test);
void (*init) (PerformanceTest *test,
gpointer data,
double factor);
void (*run) (PerformanceTest *test,
gpointer data);
void (*finish) (PerformanceTest *test,
gpointer data);
void (*teardown) (PerformanceTest *test,
gpointer data);
void (*print_result) (PerformanceTest *test,
gpointer data,
double time);
};
static void
run_test (PerformanceTest *test)
{
gpointer data = NULL;
guint64 i, num_rounds;
double elapsed, min_elapsed, max_elapsed, avg_elapsed, factor;
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
GTimer *timer;
g_print ("Running test %s\n", test->name);
/* Set up test */
timer = g_timer_new ();
data = test->setup (test);
if (verbose)
g_print ("Warming up\n");
g_timer_start (timer);
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
/* Warm up the test by doing a few runs */
for (i = 0; i < WARM_UP_N_RUNS; i++)
{
test->init (test, data, 1.0);
test->run (test, data);
test->finish (test, data);
}
g_timer_stop (timer);
elapsed = g_timer_elapsed (timer, NULL);
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
if (verbose)
{
g_print ("Warm up time: %.2f secs\n", elapsed);
g_print ("Estimating round time\n");
}
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
/* Estimate time for one run by doing a few test rounds */
min_elapsed = 0;
for (i = 0; i < ESTIMATE_ROUND_TIME_N_RUNS; i++)
{
test->init (test, data, 1.0);
g_timer_start (timer);
test->run (test, data);
g_timer_stop (timer);
test->finish (test, data);
elapsed = g_timer_elapsed (timer, NULL);
if (i == 0)
min_elapsed = elapsed;
else
min_elapsed = MIN (min_elapsed, elapsed);
}
factor = TARGET_ROUND_TIME / min_elapsed;
if (verbose)
g_print ("Uncorrected round time: %.4f msecs, correction factor %.2f\n", 1000*min_elapsed, factor);
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
/* Calculate number of rounds needed */
num_rounds = (test_length / TARGET_ROUND_TIME) + 1;
if (verbose)
g_print ("Running %"G_GINT64_MODIFIER"d rounds\n", num_rounds);
/* Run the test */
for (i = 0; i < num_rounds; i++)
{
test->init (test, data, factor);
g_timer_start (timer);
test->run (test, data);
g_timer_stop (timer);
test->finish (test, data);
elapsed = g_timer_elapsed (timer, NULL);
if (i == 0)
max_elapsed = min_elapsed = avg_elapsed = elapsed;
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
else
{
min_elapsed = MIN (min_elapsed, elapsed);
max_elapsed = MAX (max_elapsed, elapsed);
avg_elapsed += elapsed;
}
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
}
avg_elapsed = avg_elapsed / num_rounds;
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
if (verbose)
{
g_print ("Minimum corrected round time: %.2f msecs\n", min_elapsed * 1000);
g_print ("Maximum corrected round time: %.2f msecs\n", max_elapsed * 1000);
g_print ("Average corrected round time: %.2f msecs\n", avg_elapsed * 1000);
}
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
/* Print the results */
test->print_result (test, data, min_elapsed);
/* Tear down */
test->teardown (test, data);
g_timer_destroy (timer);
}
/*************************************************************
* Simple object is a very simple small GObject subclass
* with no properties, no signals, implementing no interfaces
*************************************************************/
static GType simple_object_get_type (void);
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
#define SIMPLE_TYPE_OBJECT (simple_object_get_type ())
typedef struct _SimpleObject SimpleObject;
typedef struct _SimpleObjectClass SimpleObjectClass;
struct _SimpleObject
{
GObject parent_instance;
int val;
};
struct _SimpleObjectClass
{
GObjectClass parent_class;
};
G_DEFINE_TYPE (SimpleObject, simple_object, G_TYPE_OBJECT)
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
static void
simple_object_finalize (GObject *object)
{
G_OBJECT_CLASS (simple_object_parent_class)->finalize (object);
}
static void
simple_object_class_init (SimpleObjectClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = simple_object_finalize;
}
static void
simple_object_init (SimpleObject *simple_object)
{
simple_object->val = 42;
}
typedef struct _TestIfaceClass TestIfaceClass;
typedef struct _TestIfaceClass TestIface1Class;
typedef struct _TestIfaceClass TestIface2Class;
typedef struct _TestIfaceClass TestIface3Class;
typedef struct _TestIfaceClass TestIface4Class;
typedef struct _TestIfaceClass TestIface5Class;
typedef struct _TestIface TestIface;
struct _TestIfaceClass
{
GTypeInterface base_iface;
void (*method) (TestIface *obj);
};
static GType test_iface1_get_type (void);
static GType test_iface2_get_type (void);
static GType test_iface3_get_type (void);
static GType test_iface4_get_type (void);
static GType test_iface5_get_type (void);
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
#define TEST_TYPE_IFACE1 (test_iface1_get_type ())
#define TEST_TYPE_IFACE2 (test_iface2_get_type ())
#define TEST_TYPE_IFACE3 (test_iface3_get_type ())
#define TEST_TYPE_IFACE4 (test_iface4_get_type ())
#define TEST_TYPE_IFACE5 (test_iface5_get_type ())
static DEFINE_IFACE (TestIface1, test_iface1, NULL, NULL)
static DEFINE_IFACE (TestIface2, test_iface2, NULL, NULL)
static DEFINE_IFACE (TestIface3, test_iface3, NULL, NULL)
static DEFINE_IFACE (TestIface4, test_iface4, NULL, NULL)
static DEFINE_IFACE (TestIface5, test_iface5, NULL, NULL)
/*************************************************************
* Complex object is a GObject subclass with a properties,
* construct properties, signals and implementing an interface.
*************************************************************/
static GType complex_object_get_type (void);
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
#define COMPLEX_TYPE_OBJECT (complex_object_get_type ())
typedef struct _ComplexObject ComplexObject;
typedef struct _ComplexObjectClass ComplexObjectClass;
struct _ComplexObject
{
GObject parent_instance;
int val1;
int val2;
};
struct _ComplexObjectClass
{
GObjectClass parent_class;
void (*signal) (ComplexObject *obj);
void (*signal_empty) (ComplexObject *obj);
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
};
static void complex_test_iface_init (gpointer g_iface,
gpointer iface_data);
G_DEFINE_TYPE_EXTENDED (ComplexObject, complex_object,
G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE1, complex_test_iface_init)
G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE2, complex_test_iface_init)
G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE3, complex_test_iface_init)
G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE4, complex_test_iface_init)
G_IMPLEMENT_INTERFACE (TEST_TYPE_IFACE5, complex_test_iface_init))
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
#define COMPLEX_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), COMPLEX_TYPE_OBJECT, ComplexObject))
enum {
PROP_0,
PROP_VAL1,
PROP_VAL2
};
enum {
COMPLEX_SIGNAL,
COMPLEX_SIGNAL_EMPTY,
COMPLEX_SIGNAL_GENERIC,
COMPLEX_SIGNAL_GENERIC_EMPTY,
COMPLEX_SIGNAL_ARGS,
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
COMPLEX_LAST_SIGNAL
};
static guint complex_signals[COMPLEX_LAST_SIGNAL] = { 0 };
static void
complex_object_finalize (GObject *object)
{
G_OBJECT_CLASS (complex_object_parent_class)->finalize (object);
}
static void
complex_object_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ComplexObject *complex = COMPLEX_OBJECT (object);
switch (prop_id)
{
case PROP_VAL1:
complex->val1 = g_value_get_int (value);
break;
case PROP_VAL2:
complex->val2 = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
complex_object_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ComplexObject *complex = COMPLEX_OBJECT (object);
switch (prop_id)
{
case PROP_VAL1:
g_value_set_int (value, complex->val1);
break;
case PROP_VAL2:
g_value_set_int (value, complex->val2);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
complex_object_real_signal (ComplexObject *obj)
{
}
static void
complex_object_class_init (ComplexObjectClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = complex_object_finalize;
object_class->set_property = complex_object_set_property;
object_class->get_property = complex_object_get_property;
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
class->signal = complex_object_real_signal;
complex_signals[COMPLEX_SIGNAL] =
g_signal_new ("signal",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ComplexObjectClass, signal),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
complex_signals[COMPLEX_SIGNAL_EMPTY] =
g_signal_new ("signal-empty",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ComplexObjectClass, signal_empty),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
complex_signals[COMPLEX_SIGNAL_GENERIC] =
g_signal_new ("signal-generic",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ComplexObjectClass, signal),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
complex_signals[COMPLEX_SIGNAL_GENERIC_EMPTY] =
g_signal_new ("signal-generic-empty",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ComplexObjectClass, signal_empty),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
complex_signals[COMPLEX_SIGNAL_ARGS] =
g_signal_new ("signal-args",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (ComplexObjectClass, signal),
NULL, NULL,
g_cclosure_marshal_VOID__UINT_POINTER,
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER);
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
g_object_class_install_property (object_class,
PROP_VAL1,
g_param_spec_int ("val1",
"val1",
"val1",
0,
G_MAXINT,
42,
G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_VAL2,
g_param_spec_int ("val2",
"val2",
"val2",
0,
G_MAXINT,
43,
G_PARAM_READWRITE));
}
static void
complex_object_iface_method (TestIface *obj)
{
ComplexObject *complex = COMPLEX_OBJECT (obj);
complex->val1++;
}
static void
complex_test_iface_init (gpointer g_iface,
gpointer iface_data)
{
TestIfaceClass *iface = g_iface;
iface->method = complex_object_iface_method;
}
static void
complex_object_init (ComplexObject *complex_object)
{
complex_object->val2 = 43;
}
/*************************************************************
* Test object construction performance
*************************************************************/
#define NUM_OBJECT_TO_CONSTRUCT 10000
struct ConstructionTest {
GObject **objects;
int n_objects;
GType type;
};
static gpointer
test_construction_setup (PerformanceTest *test)
{
struct ConstructionTest *data;
data = g_new0 (struct ConstructionTest, 1);
data->type = ((GType (*)(void))test->extra_data)();
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
return data;
}
static void
test_construction_init (PerformanceTest *test,
gpointer _data,
double count_factor)
{
struct ConstructionTest *data = _data;
int n;
n = NUM_OBJECT_TO_CONSTRUCT * count_factor;
if (data->n_objects != n)
{
data->n_objects = n;
data->objects = g_new (GObject *, n);
}
}
static void
test_construction_run (PerformanceTest *test,
gpointer _data)
{
struct ConstructionTest *data = _data;
GObject **objects = data->objects;
GType type = data->type;
int i, n_objects;
n_objects = data->n_objects;
for (i = 0; i < n_objects; i++)
objects[i] = g_object_new (type, NULL);
}
static void
test_construction_finish (PerformanceTest *test,
gpointer _data)
{
struct ConstructionTest *data = _data;
int i;
for (i = 0; i < data->n_objects; i++)
g_object_unref (data->objects[i]);
}
static void
test_construction_teardown (PerformanceTest *test,
gpointer _data)
{
struct ConstructionTest *data = _data;
g_free (data->objects);
g_free (data);
}
static void
test_construction_print_result (PerformanceTest *test,
gpointer _data,
double time)
{
struct ConstructionTest *data = _data;
g_print ("Millions of constructed objects per second: %.3f\n",
data->n_objects / (time * 1000000));
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
}
/*************************************************************
* Test runtime type check performance
*************************************************************/
#define NUM_KILO_CHECKS_PER_ROUND 50
struct TypeCheckTest {
GObject *object;
int n_checks;
};
static gpointer
test_type_check_setup (PerformanceTest *test)
{
struct TypeCheckTest *data;
data = g_new0 (struct TypeCheckTest, 1);
data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
return data;
}
static void
test_type_check_init (PerformanceTest *test,
gpointer _data,
double factor)
{
struct TypeCheckTest *data = _data;
data->n_checks = factor * NUM_KILO_CHECKS_PER_ROUND;
}
/* Work around g_type_check_instance_is_a being marked "pure",
and thus only called once for the loop. */
gboolean (*my_type_check_instance_is_a) (GTypeInstance *type_instance,
GType iface_type) = &g_type_check_instance_is_a;
static void
test_type_check_run (PerformanceTest *test,
gpointer _data)
{
struct TypeCheckTest *data = _data;
volatile GObject *object = data->object;
volatile GType type, types[5];
int i, j;
types[0] = test_iface1_get_type ();
types[1] = test_iface2_get_type ();
types[2] = test_iface3_get_type ();
types[3] = test_iface4_get_type ();
types[4] = test_iface5_get_type ();
for (i = 0; i < data->n_checks; i++)
{
type = types[i%5];
for (j = 0; j < 1000; j++)
{
my_type_check_instance_is_a ((GTypeInstance *)object,
type);
}
}
}
static void
test_type_check_finish (PerformanceTest *test,
gpointer data)
{
}
static void
test_type_check_print_result (PerformanceTest *test,
gpointer _data,
double time)
{
struct TypeCheckTest *data = _data;
g_print ("Million type checks per second: %.2f\n",
data->n_checks / (1000*time));
}
static void
test_type_check_teardown (PerformanceTest *test,
gpointer _data)
{
struct TypeCheckTest *data = _data;
g_object_unref (data->object);
g_free (data);
}
/*************************************************************
* Test signal emissions performance (common code)
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
*************************************************************/
#define NUM_EMISSIONS_PER_ROUND 10000
struct EmissionTest {
GObject *object;
int n_checks;
int signal_id;
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
};
static void
test_emission_run (PerformanceTest *test,
gpointer _data)
{
struct EmissionTest *data = _data;
GObject *object = data->object;
int i;
for (i = 0; i < data->n_checks; i++)
g_signal_emit (object, data->signal_id, 0);
}
static void
test_emission_run_args (PerformanceTest *test,
gpointer _data)
{
struct EmissionTest *data = _data;
GObject *object = data->object;
int i;
for (i = 0; i < data->n_checks; i++)
g_signal_emit (object, data->signal_id, 0, 0, NULL);
}
/*************************************************************
* Test signal unhandled emissions performance
*************************************************************/
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
static gpointer
test_emission_unhandled_setup (PerformanceTest *test)
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
{
struct EmissionTest *data;
data = g_new0 (struct EmissionTest, 1);
data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
data->signal_id = complex_signals[GPOINTER_TO_INT (test->extra_data)];
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
return data;
}
static void
test_emission_unhandled_init (PerformanceTest *test,
gpointer _data,
double factor)
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
{
struct EmissionTest *data = _data;
data->n_checks = factor * NUM_EMISSIONS_PER_ROUND;
}
static void
test_emission_unhandled_finish (PerformanceTest *test,
gpointer data)
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
{
}
static void
test_emission_unhandled_print_result (PerformanceTest *test,
gpointer _data,
double time)
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
{
struct EmissionTest *data = _data;
g_print ("Emissions per second: %.0f\n",
data->n_checks / time);
}
static void
test_emission_unhandled_teardown (PerformanceTest *test,
gpointer _data)
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
{
struct EmissionTest *data = _data;
g_object_unref (data->object);
g_free (data);
}
/*************************************************************
* Test signal handled emissions performance
*************************************************************/
static void
test_emission_handled_handler (ComplexObject *obj, gpointer data)
{
}
static gpointer
test_emission_handled_setup (PerformanceTest *test)
{
struct EmissionTest *data;
data = g_new0 (struct EmissionTest, 1);
data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
data->signal_id = complex_signals[GPOINTER_TO_INT (test->extra_data)];
g_signal_connect (data->object, "signal",
G_CALLBACK (test_emission_handled_handler),
NULL);
g_signal_connect (data->object, "signal-empty",
G_CALLBACK (test_emission_handled_handler),
NULL);
g_signal_connect (data->object, "signal-generic",
G_CALLBACK (test_emission_handled_handler),
NULL);
g_signal_connect (data->object, "signal-generic-empty",
G_CALLBACK (test_emission_handled_handler),
NULL);
g_signal_connect (data->object, "signal-args",
G_CALLBACK (test_emission_handled_handler),
NULL);
return data;
}
static void
test_emission_handled_init (PerformanceTest *test,
gpointer _data,
double factor)
{
struct EmissionTest *data = _data;
data->n_checks = factor * NUM_EMISSIONS_PER_ROUND;
}
static void
test_emission_handled_finish (PerformanceTest *test,
gpointer data)
{
}
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
static void
test_emission_handled_print_result (PerformanceTest *test,
gpointer _data,
double time)
{
struct EmissionTest *data = _data;
g_print ("Emissions per second: %.0f\n",
data->n_checks / time);
}
static void
test_emission_handled_teardown (PerformanceTest *test,
gpointer _data)
{
struct EmissionTest *data = _data;
g_object_unref (data->object);
g_free (data);
}
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
/*************************************************************
* Test object refcount performance
*************************************************************/
#define NUM_KILO_REFS_PER_ROUND 100000
struct RefcountTest {
GObject *object;
int n_checks;
};
static gpointer
test_refcount_setup (PerformanceTest *test)
{
struct RefcountTest *data;
data = g_new0 (struct RefcountTest, 1);
data->object = g_object_new (COMPLEX_TYPE_OBJECT, NULL);
return data;
}
static void
test_refcount_init (PerformanceTest *test,
gpointer _data,
double factor)
{
struct RefcountTest *data = _data;
data->n_checks = factor * NUM_KILO_REFS_PER_ROUND;
}
static void
test_refcount_run (PerformanceTest *test,
gpointer _data)
{
struct RefcountTest *data = _data;
GObject *object = data->object;
int i;
for (i = 0; i < data->n_checks; i++)
{
g_object_ref (object);
g_object_ref (object);
g_object_ref (object);
g_object_unref (object);
g_object_unref (object);
g_object_ref (object);
g_object_ref (object);
g_object_unref (object);
g_object_unref (object);
g_object_unref (object);
}
}
static void
test_refcount_finish (PerformanceTest *test,
gpointer _data)
{
}
static void
test_refcount_print_result (PerformanceTest *test,
gpointer _data,
double time)
{
struct RefcountTest *data = _data;
g_print ("Million refs+unref per second: %.2f\n",
data->n_checks * 5 / (time * 1000000 ));
}
static void
test_refcount_teardown (PerformanceTest *test,
gpointer _data)
{
struct RefcountTest *data = _data;
g_object_unref (data->object);
g_free (data);
}
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
/*************************************************************
* Main test code
*************************************************************/
static PerformanceTest tests[] = {
{
"simple-construction",
simple_object_get_type,
test_construction_setup,
test_construction_init,
test_construction_run,
test_construction_finish,
test_construction_teardown,
test_construction_print_result
},
{
"complex-construction",
complex_object_get_type,
test_construction_setup,
test_construction_init,
test_construction_run,
test_construction_finish,
test_construction_teardown,
test_construction_print_result
},
{
"type-check",
NULL,
test_type_check_setup,
test_type_check_init,
test_type_check_run,
test_type_check_finish,
test_type_check_teardown,
test_type_check_print_result
},
{
"emit-unhandled",
GINT_TO_POINTER (COMPLEX_SIGNAL),
test_emission_unhandled_setup,
test_emission_unhandled_init,
test_emission_run,
test_emission_unhandled_finish,
test_emission_unhandled_teardown,
test_emission_unhandled_print_result
},
{
"emit-unhandled-empty",
GINT_TO_POINTER (COMPLEX_SIGNAL_EMPTY),
test_emission_unhandled_setup,
test_emission_unhandled_init,
test_emission_run,
test_emission_unhandled_finish,
test_emission_unhandled_teardown,
test_emission_unhandled_print_result
},
{
"emit-unhandled-generic",
GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC),
test_emission_unhandled_setup,
test_emission_unhandled_init,
test_emission_run,
test_emission_unhandled_finish,
test_emission_unhandled_teardown,
test_emission_unhandled_print_result
},
{
"emit-unhandled-generic-empty",
GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC_EMPTY),
test_emission_unhandled_setup,
test_emission_unhandled_init,
test_emission_run,
test_emission_unhandled_finish,
test_emission_unhandled_teardown,
test_emission_unhandled_print_result
},
{
"emit-unhandled-args",
GINT_TO_POINTER (COMPLEX_SIGNAL_ARGS),
test_emission_unhandled_setup,
test_emission_unhandled_init,
test_emission_run_args,
test_emission_unhandled_finish,
test_emission_unhandled_teardown,
test_emission_unhandled_print_result
},
{
"emit-handled",
GINT_TO_POINTER (COMPLEX_SIGNAL),
test_emission_handled_setup,
test_emission_handled_init,
test_emission_run,
test_emission_handled_finish,
test_emission_handled_teardown,
test_emission_handled_print_result
},
{
"emit-handled-empty",
GINT_TO_POINTER (COMPLEX_SIGNAL_EMPTY),
test_emission_handled_setup,
test_emission_handled_init,
test_emission_run,
test_emission_handled_finish,
test_emission_handled_teardown,
test_emission_handled_print_result
},
{
"emit-handled-generic",
GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC),
test_emission_handled_setup,
test_emission_handled_init,
test_emission_run,
test_emission_handled_finish,
test_emission_handled_teardown,
test_emission_handled_print_result
},
{
"emit-handled-generic-empty",
GINT_TO_POINTER (COMPLEX_SIGNAL_GENERIC_EMPTY),
test_emission_handled_setup,
test_emission_handled_init,
test_emission_run,
test_emission_handled_finish,
test_emission_handled_teardown,
test_emission_handled_print_result
},
{
"emit-handled-args",
GINT_TO_POINTER (COMPLEX_SIGNAL_ARGS),
test_emission_handled_setup,
test_emission_handled_init,
test_emission_run_args,
test_emission_handled_finish,
test_emission_handled_teardown,
test_emission_handled_print_result
},
{
"refcount",
NULL,
test_refcount_setup,
test_refcount_init,
test_refcount_run,
test_refcount_finish,
test_refcount_teardown,
test_refcount_print_result
Add performance tests for GObject primitives These are basic performance test for a couple of basic gobject primitives: * construction of simple objects. Simple is a bare gobject derived class with no properties, signals or interfaces. * construction of complex objects. Complex is a gobject subclass with construct properties, normal properties, signals, and implements an interface. * run-time type check of complex objects * signal emissions Lots of care is taken to try to make the results reproducible. Each test is run for multible "rounds", where we try to make each round be "not too short" in order to be significant wrt timer accuracy, but also "not to long" to make the probability of some other random event happening on the system (interrupts, other process scheduled, etc) during the round less likely. The current target round time is 4 msecs, which was picked without rigour, but seems small wrt e.g. scheduler time. For each test we then run the calculated round size for 60 seconds, and then report the performance based on the minimal time of one round. The model here is that any random stuff that happens during a round can only slow it down, there is nothing that can make it go faster, so the minimal time is the best estimate of how fast one round goes. The result is not ideal, even on a "idle" system the results vary from round to round, but the variation seems to be less than 1%. So, any performance difference reported by this test over 1% is probably statistically significant. Additionally the tests can be run with or without threads being initialized. The script tests/gobject/run-performance.sh makes it easy to produce a performance report for the current checkout. https://bugzilla.gnome.org/show_bug.cgi?id=557100
2009-08-20 14:34:51 +02:00
}
};
static PerformanceTest *
find_test (const char *name)
{
int i;
for (i = 0; i < G_N_ELEMENTS (tests); i++)
{
if (strcmp (tests[i].name, name) == 0)
return &tests[i];
}
return NULL;
}
int
main (int argc,
char *argv[])
{
PerformanceTest *test;
GOptionContext *context;
GError *error = NULL;
int i;
context = g_option_context_new ("GObject performance tests");
g_option_context_add_main_entries (context, cmd_entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
if (argc > 1)
{
for (i = 1; i < argc; i++)
{
test = find_test (argv[i]);
if (test)
run_test (test);
}
}
else
{
for (i = 0; i < G_N_ELEMENTS (tests); i++)
run_test (&tests[i]);
}
return 0;
}