Re: Some performance notes
- From: Tim Janik <timj gtk org>
- To: Owen Taylor <otaylor redhat com>
- Cc: Johannes Stezenbach <js convergence de>, Sebastian Wilhelmi <wilhelmi ira uka de>, Gtk+ Developers <gtk-devel-list gnome org>
- Subject: Re: Some performance notes
- Date: Tue, 7 Aug 2001 06:39:41 +0200 (CEST)
On 6 Aug 2001, Owen Taylor wrote:
> > > > After I removed the g_object_class_install_property() stuff,
> > > > object creation was faster, but is still way to slow compared
> > > > to just malloc'ing plain C structs for holding the data.
> >
> > assuming you don't use CONSTRUCT properties, i find this mildly
> > odd, can you provide two stand-alone test cases, one with the
> > g_object_class_install_property() stuff and one without?
> >
> > > I can see places in the g_object_new()/g_type_create_instance()
> > > code paths which look like they could be optimized, but
> > > in the absence of real benchmarking information, that's
> > > fairly theoretical.
> >
> > even if theoretical, i'd be interested in hearing what you'd want
> > to speed-up there, especially for g_type_create_instance().
>
> * g_type_create_instance() Looks up the type node, involving a
> separate lock/unlock 3 times. Two of these could be avoided with
> private functions (at the expense of some code bloat)
we can't get rid of the write lock for prealloced types, and need
a read lock initially to get a hand at the type node to create an
instance for, but i guess we can get rid of the locks in the for()
loop which chains parent class intializers with storing type nodes
in supers[].
> * G_TYPE_IS_ABSTRACT() is fairly expensive, so the check
> probably should be surrounded by #ifndef G_DISABLE_CHECKS
nope, instead G_TYPE_IS_ABSTRACT() should - at least internally -
be just a flag test, that's on of the TODO items at the top of
gtype.c:
* - speedup checks for virtual types, steal a bit somewhere
> * If node->supers was stored as type nodes, not types, then
> the walk over the supers to initialize could be done
> without locking, since node->supers, and the relevant
> parts of the type nodes are static once they are created.
good point. looking this over, storing type node pointers in
supers[] has the drawbacks:
- on sizeof(pointer)==8 systems, we increase memory usage by
4*depth(foreach typenode) bytes
- all type nodes grow by an extra int to store the actual type id
- NODE_PARENT_TYPE() gains an extra indirection
however, as benefits, this will get rid of:
- a couple extra locks upon instance creation
- a few indirections upon is_a checks
- lookups such as lookup_type_node_L (prerequisite_node->supers[i])
also the NODE_PARENT_TYPE() drawback is prolly negligible as that
macro is used as lookup_type_node_L (NODE_PARENT_TYPE (node)) in
a couple places.
> That's what I see offhand in g_type_create_instance(). Without
> profiling data and some tests, I have no idea whether any of these
> area actually worthwhile changes.
>
> (Object creation and destruction did not show up at all
> on my radar, but I wasn't profiling startup, just drawing.
> Even startup I think will be much more dominated by
> signal emission.)
yup, i'd second that.
> > > A pretty noticeable improvement for the non-threaded case
> > > would be to reduce locking overhead when we aren't
> > > initialized for threads.
> > >
> > > #define G_READ_LOCK(rw_lock) g_static_rw_lock_reader_lock (rw_lock)
> > >
> > > in gobject.c is always a function call, but if you trace
> > > down the G_LOCK() macro used elsewhere, you'll see it doesn't
> > > make a function call unless threading is enabled.
> >
> > do you have any indication of g_static_rw_lock_reader_lock() actually
> > consuming significant time for the non-threaded case?
>
> Yes, in my profiling (debug off) it was eating about 4% of the
> CPU time.
wow, that requires further investigation, as i vaguely remember a
profile of sebastian that indicated locks being pretty fast for
the non-threaded case.
> > > For the threaded case, some attention to locking and unlocking
> > > less would be good - for instance, look up a type node and
> > > keep the result, instead of keeping locking and looking it
> > > up.
> >
> > i'm not sure what you are imagining here, usually the type system
> > acquires and releases a read-lock per function call in order
> > to be able to lookup type nodes, unless callbacks are being called,
> > in which case locks have to be released.
> > obviously, type nodes can't be cached across different API entries
> > of the type system, so i'm not quite getting what you're aiming at.
>
> In some cases, it may pay to add private entry points that take
> type nodes, rather than types.
take a look at the static functions, all of them that can, do indeed
already take a TypeNode* and not a GType already.
>
> Regards,
> Owen
>
---
ciaoTJ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]