gobject bench
- From: Havoc Pennington <hp redhat com>
- To: gtk-devel-list gnome org
- Subject: gobject bench
- Date: 27 Aug 2000 17:48:31 -0400
Hi,
I wrote a little program and did some timings (celeron 400):
Creating lots of objects...
Created 1000000 GObject instances in 0.86 seconds (8.6e-07 secs per object)
Finalized 1000000 GObject instances in 1.01 seconds (1.01e-06 secs per object)
Creating lots of zero-filled structs...
Created 1000000 struct instances in 0.47 seconds (4.7e-07 secs per object)
Finalized 1000000 struct instances in 0.59 seconds (5.9e-07 secs per object)
Oddly, per the comment in the source, using G_OBJECT(g_object_new())
instead of (GObject*)g_type_create_instance() halves the speed of
object creation. Removing the G_OBJECT() typecast from the unref()
loop doesn't make any noticeable difference, so it must just be the
set_valist() and other stuff in g_object_new(). Could likely optimize
the common case where first_param_name == NULL by returning
immediately.
So anyway, this seems to demonstrate that the time overhead of GObject
creation is pretty low, about a constant factor of 2 more than a plain
calloc() struct, including custom init/finalize methods. This suggests
that speed should not be a concern when deciding whether to make a
type a GObject or a plain struct; probably the size of the struct is
the only real issue, if you have a huge number of instances and only a
couple fields then GObject could cause some bloat. Also of course
GObject prevents static allocation, which can matter for something
like PangoFontDescription.
I can check in the bench program if you want, I don't guess it's that
exciting though.
Havoc
#include "config.h"
#include <glib-object.h>
#include <time.h>
#include <stdio.h>
typedef struct _GBench GBench;
typedef struct _GBenchClass GBenchClass;
#define G_TYPE_BENCH (g_bench_get_type ())
#define G_BENCH(object) (G_TYPE_CHECK_INSTANCE_CAST
#((object), G_TYPE_BENCH, GBench))
#define G_BENCH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
#G_TYPE_BENCH, GBenchClass))
#define G_IS_BENCH(object) (G_TYPE_CHECK_INSTANCE_TYPE
#((object), G_TYPE_BENCH))
#define G_IS_BENCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
#G_TYPE_BENCH))
#define G_BENCH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
#G_TYPE_BENCH, GBenchClass))
struct _GBench
{
GObject parent_instance;
gint some_member_data;
gpointer other_data;
};
struct _GBenchClass
{
GObjectClass parent_class;
};
GType g_bench_get_type (void);
#define ITERATIONS 1000000
int
main (gint argc,
gchar *argv[])
{
clock_t start;
clock_t end;
gint i;
GBench *benches[ITERATIONS];
g_type_init ();
printf ("Creating lots of objects...\n");
start = clock ();
i = 0;
while (i < ITERATIONS)
{
/* writing this as "G_OBJECT (g_object_new(G_TYPE_OBJECT,
NULL))"
* results in nearly doubling the time this loop takes to run.
* Go figure.
*/
benches[i] = (GBench*)g_type_create_instance (G_TYPE_OBJECT);
++i;
}
end = clock ();
printf ("Created %d GObject instances in %g seconds (%g secs per
object)\n",
ITERATIONS,
(end - start)/(double)CLOCKS_PER_SEC,
(end - start)/(double)CLOCKS_PER_SEC/(double)ITERATIONS);
start = clock ();
i = 0;
while (i < ITERATIONS)
{
g_object_unref (G_OBJECT (benches[i]));
++i;
}
end = clock ();
printf ("Finalized %d GObject instances in %g seconds (%g secs per
object)\n",
ITERATIONS,
(end - start)/(double)CLOCKS_PER_SEC,
(end - start)/(double)CLOCKS_PER_SEC/(double)ITERATIONS);
printf ("Creating lots of zero-filled structs...\n");
start = clock ();
i = 0;
while (i < ITERATIONS)
{
benches[i] = g_new0(GBench, 1);
++i;
}
end = clock ();
printf ("Created %d struct instances in %g seconds (%g secs per
object)\n",
ITERATIONS,
(end - start)/(double)CLOCKS_PER_SEC,
(end - start)/(double)CLOCKS_PER_SEC/(double)ITERATIONS);
start = clock ();
i = 0;
while (i < ITERATIONS)
{
g_free (benches[i]);
++i;
}
end = clock ();
printf ("Finalized %d struct instances in %g seconds (%g secs per
object)\n",
ITERATIONS,
(end - start)/(double)CLOCKS_PER_SEC,
(end - start)/(double)CLOCKS_PER_SEC/(double)ITERATIONS);
return 0;
}
static void g_bench_init (GBench *bench);
static void g_bench_class_init (GBenchClass *klass);
static void g_bench_finalize (GObject *object);
static gpointer parent_class;
GType
g_bench_get_type (void)
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info =
{
sizeof (GBenchClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) g_bench_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GBench),
0, /* n_preallocs */
(GInstanceInitFunc) g_bench_init,
};
object_type = g_type_register_static (G_TYPE_OBJECT,
"GBench",
&object_info);
}
return object_type;
}
static void
g_bench_init (GBench *bench)
{
bench->some_member_data = 100;
bench->other_data = NULL;
}
static void
g_bench_class_init (GBenchClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = g_bench_finalize;
}
static void
g_bench_finalize (GObject *object)
{
GBench *bench;
bench = G_BENCH (object);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]