GNOME Bugzilla – Bug 689847
Add fast repeated typename -> GType resolver
Last modified: 2012-12-10 11:58:23 UTC
This is needed for the Gtk+ css matching system that lets you match against typenames.
Created attachment 230972 [details] [review] Add GTypeReference for fast repeated name -> type lookups The Gtk+ themeing system suports matching by type name, and it turns out that repeatedly calling g_type_from_name() is pretty slow. But, we can't pre-convert to a GType because a lot of the types in use are not yet registred, but may be registred later. So, we introduce an object that represents a name->gtype mapping, which can be instantiated even for currently non-registred types, which will handle the case of a type later being registred. Using this made my EggListBox test case 6% faster going to/from backdrop mode.
Created attachment 230973 [details] [review] css: Use GTypeReference to speed up name matching
Created attachment 230983 [details] [review] css: Speed up name matching We use the new g_type_get_type_registration_serial() so that we can cache and properly invalidate the result of g_type_from_name().
Created attachment 230984 [details] [review] Add g_type_get_type_registration_serial() This lets you cache type lookup information and then know when the cache information is out of date. In particular, we want this in order to be able to cache g_type_from_name() lookups in the Gtk+ theme machinery.
Review of attachment 230972 [details] [review]: As discussed on IRC, this is just too evil...
Review of attachment 230984 [details] [review]: I'm happy with this approach. Please only commit this at the same time as the Gtk patch (to make sure it's really what you need).
Review of attachment 230983 [details] [review]: ::: gtk/gtkcssselector.c @@ +551,3 @@ + + return ref; +} How big does this table get ? @@ +575,3 @@ + ref->type = g_type_from_name (ref->name); + } +} Instead of doing this full loop over the hash table, you could do the recheck at lookup time, if you stored the serial with the ref: ref = g_hash_table_lookup (name) if (ref) { if (ref->type == G_TYPE_INVALID) { serial = g_type_get_registration_serial(); if (ref->serial != serial) { ref->type = g_type_from_name (ref->name); ref->serial = serial; } return ref; } Maybe not worth it...
Review of attachment 230984 [details] [review]: ::: gobject/gtype.c @@ +398,3 @@ + * g_type_get_type_registration_serial: + * + * Returns an opaque serial number that represents the state of the set of registred registered, not registred
Review of attachment 230983 [details] [review]: ::: gtk/gtkcssselector.c @@ +551,3 @@ + + return ref; +} I'll check @@ +575,3 @@ + ref->type = g_type_from_name (ref->name); + } +} Well, this slows down the fast path with multiple checks per lookup for a very uncommon case (got new types). Additionally it needs to store the serial in more places, and, most css typechecks has the typename at the rightmost so will be at the topmost of the tree and will thus be checked every time anyway, so we do as many checks anyway.
With current adwaita the table is 69 entries. i.e. 1104 bytes on 64bit and 552 bytes on 32bit. Thats assuming no malloc overhead though, so i'm changing this to use GSlice which should let us basically reach that (the struct size is the same as the GSList one, so we'll have other things of this size anyway).
Comment on attachment 230984 [details] [review] Add g_type_get_type_registration_serial() Attachment 230984 [details] pushed as e218b96 - Add g_type_get_type_registration_serial()
Attachment 230983 [details] pushed as a1ee2b7 - css: Speed up name matching