Introduce g_object_notify_by_pspec()

g_object_notify_by_pspec() will emit the "notify" signal on the given
pspec, short-circuiting the hash table lookup needed by
g_object_notify(). The suggested and documented way of using
g_object_notify_by_pspec() is similar to the way of emitting signals
with their ID.

Emission tests (with no handler attached to the notify signal) show a
10-15% speedup over using g_object_notify().

https://bugzilla.gnome.org/show_bug.cgi?id=615425
This commit is contained in:
Damien Lespiau 2010-04-10 15:50:40 +01:00 committed by Emmanuele Bassi
parent 08f473ffef
commit f3879a4bdc
4 changed files with 79 additions and 7 deletions

View File

@ -269,6 +269,7 @@ g_object_disconnect
g_object_set
g_object_get
g_object_notify
g_object_notify_by_pspec
g_object_freeze_notify
g_object_thaw_notify
g_object_get_data

View File

@ -849,12 +849,27 @@ g_object_freeze_notify (GObject *object)
g_object_unref (object);
}
static inline void
g_object_notify_by_spec_internal (GObject *object,
GParamSpec *pspec)
{
GObjectNotifyQueue *nqueue;
nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
g_object_notify_queue_add (object, nqueue, pspec);
g_object_notify_queue_thaw (object, nqueue);
}
/**
* g_object_notify:
* @object: a #GObject
* @property_name: the name of a property installed on the class of @object.
*
* Emits a "notify" signal for the property @property_name on @object.
*
* When possible, eg. when signaling a property change from within the class
* that registered the property, you should use g_object_notify_by_pspec()
* instead.
*/
void
g_object_notify (GObject *object,
@ -883,13 +898,66 @@ g_object_notify (GObject *object,
G_OBJECT_TYPE_NAME (object),
property_name);
else
{
GObjectNotifyQueue *nqueue;
g_object_notify_by_spec_internal (object, pspec);
g_object_unref (object);
}
nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
g_object_notify_queue_add (object, nqueue, pspec);
g_object_notify_queue_thaw (object, nqueue);
}
/**
* g_object_notify_by_pspec:
* @object: a #GObject
* @pspec: the #GParamSpec of a property installed on the class of @object.
*
* Emits a "notify" signal for the property specified by @pspec on @object.
*
* This function omits the property name lookup, hence it is faster than
* g_object_notify().
*
* One way to avoid using g_object_notify() from within the
* class that registered the properties, and using g_object_notify_by_pspec()
* instead, is to store the GParamSpec used with
* g_object_class_install_property() inside a static array, e.g.:
*
*|[
* enum
* {
* PROP_0,
* PROP_FOO,
* PROP_LAST
* };
*
* static GParamSpec *properties[PROP_LAST];
*
* static void
* my_object_class_init (MyObjectClass *klass)
* {
* properties[PROP_FOO] = g_param_spec_int ("foo", "Foo", "The foo",
* 0, 100,
* 50,
* G_PARAM_READWRITE);
* g_object_class_install_property (gobject_class,
* PROP_FOO,
* properties[PROP_FOO]);
* }
* ]|
*
* and then notify a change on the "foo" property with:
*
* |[
* g_object_notify_by_pspec (self, properties[PROP_FOO]);
* ]|
*
* Since: 2.26
*/
void
g_object_notify_by_pspec (GObject *object,
GParamSpec *pspec)
{
g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_object_ref (object);
g_object_notify_by_spec_internal (object, pspec);
g_object_unref (object);
}

View File

@ -435,6 +435,8 @@ void g_object_get_property (GObject *object,
void g_object_freeze_notify (GObject *object);
void g_object_notify (GObject *object,
const gchar *property_name);
void g_object_notify_by_pspec (GObject *object,
GParamSpec *pspec);
void g_object_thaw_notify (GObject *object);
gboolean g_object_is_floating (gpointer object);
gpointer g_object_ref_sink (gpointer object);

View File

@ -141,6 +141,7 @@ g_object_new
g_object_newv
g_object_new_valist
g_object_notify
g_object_notify_by_pspec
g_object_is_floating
g_object_ref_sink
g_object_force_floating