Re: gobject bench
- From: Tim Janik <timj gtk org>
- To: Havoc Pennington <hp redhat com>
- Cc: gtk-devel-list gnome org
- Subject: Re: gobject bench
- Date: Tue, 29 Aug 2000 01:03:33 +0200 (CEST)
On 27 Aug 2000, Havoc Pennington wrote:
>
> 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.
ok, first, just for comparison, rerunning your bench program
on my machine, i.e.:
model name : Pentium III (Katmai)
stepping : 3
cpu MHz : 551.261
cache size : 512 KB
results in:
>Creating lots of objects...
>Created 1000000 GObject instances in 0.64 seconds (6.4e-07 secs per object)
>Finalized 1000000 GObject instances in 1.19 seconds (1.19e-06 secs per object)
>Creating lots of zero-filled structs...
>Created 1000000 struct instances in 0.35 seconds (3.5e-07 secs per object)
>Finalized 1000000 struct instances in 0.43 seconds (4.3e-07 secs per object)
then actually making use of your GBench implementation, by changing:
- benches[i] = (GBench*)g_type_create_instance (G_TYPE_OBJECT);
+ benches[i] = (GBench*)g_type_create_instance (G_TYPE_BENCH);
produces:
>Creating lots of objects...
>Created 1000000 GObject instances in 0.78 seconds (7.8e-07 secs per object)
>Finalized 1000000 GObject instances in 1.92 seconds (1.92e-06 secs per object)
>Creating lots of zero-filled structs...
>Created 1000000 struct instances in 0.3 seconds (3e-07 secs per object)
>Finalized 1000000 struct instances in 0.4 seconds (4e-07 secs per object)
interestingly to note, just adding one more cast:
- benches[i] = (GBench*)g_type_create_instance (G_TYPE_OBJECT);
+ benches[i] = G_BENCH(g_type_create_instance (G_TYPE_BENCH));
results in:
>Creating lots of objects...
>Created 1000000 GObject instances in 1.06 seconds (1.06e-06 secs per object)
>Finalized 1000000 GObject instances in 1.91 seconds (1.91e-06 secs per object)
>Creating lots of zero-filled structs...
>Created 1000000 struct instances in 0.3 seconds (3e-07 secs per object)
>Finalized 1000000 struct instances in 0.43 seconds (4.3e-07 secs per object)
so there's quite some overhead introduced by casting to a derived type.
thusly adding #define G_DISABLE_CAST_CHECKS prior to glib-object.h
inclusion goes back to 0.78 seconds for object creation, and because of
static void
g_bench_finalize (GObject *object)
{
GBench *bench;
bench = G_BENCH (object);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
it also cuts on finalization time:
>Creating lots of objects...
>Created 1000000 GObject instances in 0.74 seconds (7.4e-07 secs per object)
>Finalized 1000000 GObject instances in 1.06 seconds (1.06e-06 secs per object)
>Creating lots of zero-filled structs...
>Created 1000000 struct instances in 0.3 seconds (3e-07 secs per object)
>Finalized 1000000 struct instances in 0.4 seconds (4e-07 secs per object)
from there, switching to g_object_new():
- benches[i] = G_BENCH(g_type_create_instance (G_TYPE_BENCH));
+ benches[i] = G_BENCH(g_object_new (G_TYPE_BENCH,NULL));
yields:
>Creating lots of objects...
>Created 1000000 GObject instances in 0.87 seconds (8.7e-07 secs per object)
>Finalized 1000000 GObject instances in 1.1 seconds (1.1e-06 secs per object)
>Creating lots of zero-filled structs...
>Created 1000000 struct instances in 0.32 seconds (3.2e-07 secs per object)
>Finalized 1000000 struct instances in 0.38 seconds (3.8e-07 secs per object)
that's not much overhead for 1000000 object creations at all.
considering that g_object_new() internally does call g_object_new_valist(),
which then _does_ check first_param_name != NULL before calling
g_object_set_valist(), the additional overhead is prolly just caused by
the two extra function calls and twice doing:
g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL);
btw, judging from the jitter in the above numbers and from what i encountered
upon multiple invokations of the same compiled version, the sampling error is
probably somewhere around 0.05 seconds, so take these numbers with an
apropriate amount of salt ;)
> 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
you didn't create GBranch but GObject in your testfile, so you weren't
using the customized initializers/finalizers. (that's why i pasted
multiple test cases above)
> 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.
i might extend it to do some signal emission tests, so don't be
amazed if gbench.c finally ends up somewhere in CVS ;)
>
> Havoc
>
---
ciaoTJ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]