[glib/g-property: 2/3] perf: Compare GParamSpec and GProperty usage



commit bbee96f5a46e507552a20bed7ad8858a63fd797e
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Tue May 17 13:40:39 2011 +0100

    perf: Compare GParamSpec and GProperty usage
    
    Use g_object_set() and g_object_get(), since direct function access is
    not an interesting benchmark.
    
    The code simply sets and gets the properties of a GObject class, once
    created using GParamSpec and overriding GObject::set_property and
    GObject::get_property virtual functions; then using GProperty and direct
    access over the private data structure field. The implementation of the
    GParamSpec accessors are equivalent to the GProperty internal code.
    
    On my X200s, with a 1.86 GHz Core 2 Duo, the results are:
    
      Running test gparamspec-property
      Number of accesses per second: 103422
      Running test gproperty-property
      Number of accesses per second: 155550
    
    for 3 properties of types int, gchar* and float respectively, and
    
      Running test gparamspec-property
      Number of accesses per second: 123298
      Running test gproperty-property
      Number of accesses per second: 259618
    
    for 2 properties of types int and float.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=648526

 tests/gobject/performance.c |  392 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 392 insertions(+), 0 deletions(-)
---
diff --git a/tests/gobject/performance.c b/tests/gobject/performance.c
index c626916..65bd8d9 100644
--- a/tests/gobject/performance.c
+++ b/tests/gobject/performance.c
@@ -385,6 +385,280 @@ complex_object_init (ComplexObject *complex_object)
   complex_object->val2 = 43;
 }
 
+/****************************************************************
+ * ParamspecObject is an object using GParamSpec for properties *
+ ****************************************************************/
+
+#define PARAMSPEC_TYPE_OBJECT           (paramspec_object_get_type ())
+typedef struct _ParamspecObject         ParamspecObject;
+typedef struct _ParamspecObjectClass    ParamspecObjectClass;
+typedef struct _ParamspecObjectPrivate  ParamspecObjectPrivate;
+
+struct _ParamspecObject
+{
+  GObject parent_instance;
+
+  ParamspecObjectPrivate *priv;
+};
+
+struct _ParamspecObjectClass
+{
+  GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (ParamspecObject, paramspec_object, G_TYPE_OBJECT)
+
+#define PARAMSPEC_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PARAMSPEC_TYPE_OBJECT, ParamspecObject))
+
+struct _ParamspecObjectPrivate
+{
+  int foo;
+  gchar *bar;
+  float baz;
+};
+
+enum {
+  PROP_PSPEC_0,
+  PROP_PSPEC_FOO,
+  PROP_PSPEC_BAR,
+  PROP_PSPEC_BAZ,
+  PROP_PSPEC_LAST
+};
+
+static GParamSpec *pspec_props[PROP_PSPEC_LAST] = { NULL, };
+
+static void
+paramspec_object_finalize (GObject *object)
+{
+  ParamspecObjectPrivate *priv = PARAMSPEC_OBJECT (object)->priv;
+
+  g_free (priv->bar);
+
+  G_OBJECT_CLASS (paramspec_object_parent_class)->finalize (object);
+}
+
+static void
+paramspec_object_set_foo (ParamspecObject *object,
+                          int              value)
+{
+  if (object->priv->foo == value)
+    return;
+
+  object->priv->foo = value;
+
+  g_object_notify_by_pspec (G_OBJECT (object), pspec_props[PROP_PSPEC_FOO]);
+}
+
+static void
+paramspec_object_set_bar (ParamspecObject *object,
+                          const char      *value)
+{
+  if (g_strcmp0 (object->priv->bar, value) == 0)
+    return;
+
+  g_free (object->priv->bar);
+  object->priv->bar = g_strdup (value);
+
+  g_object_notify_by_pspec (G_OBJECT (object), pspec_props[PROP_PSPEC_BAR]);
+}
+
+static void
+paramspec_object_set_baz (ParamspecObject *object,
+                          float            value)
+{
+  if (object->priv->baz == value)
+    return;
+
+  object->priv->baz = value;
+
+  g_object_notify_by_pspec (G_OBJECT (object), pspec_props[PROP_PSPEC_BAZ]);
+}
+
+static void
+paramspec_object_set_property (GObject         *object,
+                               guint            prop_id,
+                               const GValue    *value,
+                               GParamSpec      *pspec)
+{
+  switch (prop_id)
+    {
+    case PROP_PSPEC_FOO:
+      paramspec_object_set_foo (PARAMSPEC_OBJECT (object), g_value_get_int (value));
+      break;
+    case PROP_PSPEC_BAR:
+      paramspec_object_set_bar (PARAMSPEC_OBJECT (object), g_value_get_string (value));
+      break;
+    case PROP_PSPEC_BAZ:
+      paramspec_object_set_baz (PARAMSPEC_OBJECT (object), g_value_get_float (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+paramspec_object_get_property (GObject         *object,
+                               guint            prop_id,
+                               GValue          *value,
+                               GParamSpec      *pspec)
+{
+  switch (prop_id)
+    {
+    case PROP_PSPEC_FOO:
+      g_value_set_int (value, PARAMSPEC_OBJECT (object)->priv->foo);
+      break;
+    case PROP_PSPEC_BAR:
+      g_value_set_string (value, PARAMSPEC_OBJECT (object)->priv->bar);
+      break;
+    case PROP_PSPEC_BAZ:
+      g_value_set_float (value, PARAMSPEC_OBJECT (object)->priv->baz);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+paramspec_object_class_init (ParamspecObjectClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  g_type_class_add_private (class, sizeof (ParamspecObjectPrivate));
+
+  object_class->finalize = paramspec_object_finalize;
+  object_class->set_property = paramspec_object_set_property;
+  object_class->get_property = paramspec_object_get_property;
+
+  pspec_props[PROP_PSPEC_FOO] =
+    g_param_spec_int ("foo",
+                      NULL, NULL,
+                      -100, 100, 50,
+                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+  pspec_props[PROP_PSPEC_BAR] =
+    g_param_spec_string ("bar",
+                         NULL, NULL,
+                         "Hello",
+                         G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+  pspec_props[PROP_PSPEC_BAZ] =
+    g_param_spec_float ("baz",
+                        NULL, NULL,
+                        0.0f, G_MAXFLOAT, 0.0f,
+                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (object_class, PROP_PSPEC_LAST, pspec_props);
+}
+
+static void
+paramspec_object_init (ParamspecObject *self)
+{
+  self->priv = g_type_instance_get_private ((GTypeInstance *) self, PARAMSPEC_TYPE_OBJECT);
+
+  self->priv->foo = 50;
+  self->priv->bar = g_strdup ("Hello");
+  self->priv->baz = 0.0f;
+}
+
+/**************************************************************
+ * PropertyObject is an object using GProperty for properties *
+ **************************************************************/
+
+#define PROPERTY_TYPE_OBJECT           (property_object_get_type ())
+typedef struct _PropertyObject         PropertyObject;
+typedef struct _PropertyObjectClass    PropertyObjectClass;
+typedef struct _PropertyObjectPrivate  PropertyObjectPrivate;
+
+struct _PropertyObject
+{
+  GObject parent_instance;
+
+  PropertyObjectPrivate *priv;
+};
+
+struct _PropertyObjectClass
+{
+  GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (PropertyObject, property_object, G_TYPE_OBJECT)
+
+#define PROPERTY_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PROPERTY_TYPE_OBJECT, PropertyObject))
+
+struct _PropertyObjectPrivate
+{
+  int foo;
+  gchar *bar;
+  float baz;
+};
+
+enum {
+  PROP_PROPERTY_0,
+  PROP_PROPERTY_FOO,
+  PROP_PROPERTY_BAR,
+  PROP_PROPERTY_BAZ,
+  PROP_PROPERTY_LAST
+};
+
+static GParamSpec *property_props[PROP_PROPERTY_LAST] = { NULL, };
+
+static void
+property_object_finalize (GObject *object)
+{
+  PropertyObjectPrivate *priv = PROPERTY_OBJECT (object)->priv;
+
+  g_free (priv->bar);
+
+  G_OBJECT_CLASS (property_object_parent_class)->finalize (object);
+}
+
+static void
+property_object_class_init (PropertyObjectClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  g_type_class_add_private (class, sizeof (PropertyObjectPrivate));
+
+  object_class->finalize = property_object_finalize;
+
+  property_props[PROP_PROPERTY_FOO] =
+    g_int_property_new ("foo", G_PROPERTY_READWRITE,
+                        G_STRUCT_OFFSET (PropertyObjectPrivate, foo),
+                        NULL, NULL);
+  g_property_set_range ((GProperty *) property_props[PROP_PROPERTY_FOO], -100, 100);
+  g_property_set_default ((GProperty *) property_props[PROP_PROPERTY_FOO], object_class, 50);
+
+  property_props[PROP_PROPERTY_BAR] =
+    g_string_property_new ("bar", G_PROPERTY_READWRITE,
+                           G_STRUCT_OFFSET (PropertyObjectPrivate, bar),
+                           NULL, NULL);
+  g_property_set_default ((GProperty *) property_props[PROP_PROPERTY_BAR], object_class, "Hello");
+
+  property_props[PROP_PROPERTY_BAZ] =
+    g_float_property_new ("baz", G_PROPERTY_READWRITE,
+                          G_STRUCT_OFFSET (PropertyObjectPrivate, baz),
+                          NULL, NULL);
+  g_property_set_range ((GProperty *) property_props[PROP_PROPERTY_BAZ], 0.0f, G_MAXFLOAT);
+
+  g_object_class_install_properties (object_class, PROP_PROPERTY_LAST, property_props);
+}
+
+static void
+property_object_init (PropertyObject *self)
+{
+  self->priv = g_type_instance_get_private ((GTypeInstance *) self, PROPERTY_TYPE_OBJECT);
+
+  g_property_get_default ((GProperty *) property_props[PROP_PROPERTY_FOO],
+                          self,
+                          &(self->priv->foo));
+  g_property_get_default ((GProperty *) property_props[PROP_PROPERTY_BAR],
+                          self,
+                          &(self->priv->bar));
+  g_property_get_default ((GProperty *) property_props[PROP_PROPERTY_BAZ],
+                          self,
+                          &(self->priv->baz));
+}
+
 /*************************************************************
  * Test object construction performance
  *************************************************************/
@@ -470,6 +744,104 @@ test_construction_print_result (PerformanceTest *test,
 }
 
 /*************************************************************
+ * Test property accessors using GParamSpec
+ *************************************************************/
+
+#define NUM_ACCESSES_PER_ROUND  10000
+
+struct PropertyTest {
+  GObject *object;
+  int n_accesses;
+};
+
+static gpointer
+test_property_setup (PerformanceTest *test)
+{
+  struct PropertyTest *data;
+  GType gtype;
+
+  gtype = ((GType (*)())test->extra_data)();
+
+  data = g_new0 (struct PropertyTest, 1);
+  data->object = g_object_new (gtype, NULL);
+
+  return data;
+}
+
+static void
+test_property_init (PerformanceTest *test,
+                    gpointer _data,
+                    double factor)
+{
+  struct PropertyTest *data = _data;
+
+  data->n_accesses = factor * NUM_ACCESSES_PER_ROUND;
+}
+
+static void
+test_property_run (PerformanceTest *test,
+                   gpointer _data)
+{
+  struct PropertyTest *data = _data;
+  int n_accesses, i;
+
+  n_accesses = data->n_accesses;
+  for (i = 0; i < n_accesses; i++)
+    {
+      gint foo = i % 16;
+      const gchar *bar = g_strdup_printf ("World/%d", foo);
+      gfloat baz = foo * 3.14f;
+
+      g_object_set (data->object,
+                    "foo", foo,
+                    "bar", bar,
+                    "baz", baz,
+                    NULL);
+    }
+
+  for (i = 0; i < n_accesses; i++)
+    {
+      gint foo;
+      gchar *bar;
+      gfloat baz;
+
+      g_object_get (data->object,
+                    "foo", &foo,
+                    "bar", &bar,
+                    "baz", &baz,
+                    NULL);
+
+      g_free (bar);
+    }
+}
+
+static void
+test_property_finish (PerformanceTest *test,
+                      gpointer _data)
+{
+}
+
+static void
+test_property_print_result (PerformanceTest *test,
+                            gpointer _data,
+                            gdouble time)
+{
+  struct PropertyTest *data = _data;
+  g_print ("Number of accesses per second: %.0f\n",
+           data->n_accesses / time);
+}
+
+static void
+test_property_teardown (PerformanceTest *test,
+                        gpointer _data)
+{
+  struct PropertyTest *data = _data;
+
+  g_object_unref (data->object);
+  g_free (data);
+}
+
+/*************************************************************
  * Test runtime type check performance
  *************************************************************/
 
@@ -659,6 +1031,26 @@ static PerformanceTest tests[] = {
     test_construction_print_result
   },
   {
+    "gparamspec-property",
+    paramspec_object_get_type,
+    test_property_setup,
+    test_property_init,
+    test_property_run,
+    test_property_finish,
+    test_property_teardown,
+    test_property_print_result
+  },
+  {
+    "gproperty-property",
+    property_object_get_type,
+    test_property_setup,
+    test_property_init,
+    test_property_run,
+    test_property_finish,
+    test_property_teardown,
+    test_property_print_result
+  },
+  {
     "type-check",
     NULL,
     test_type_check_setup,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]