From 2601011e9eb3b5f391161313ed568e5c4b67c99a Mon Sep 17 00:00:00 2001 From: Simon Feltman Date: Fri, 8 Aug 2014 23:58:17 -0700 Subject: Fast path property access for basic types Attempt marshalling with pygi_value_to_py_basic_type() prior to looking at GI info. This gives a quick conversion for basic types like bools, ints, and strings without having to go through GIArgument and GI conversions. This gives approximately a 3x performance boost for accessing these types with the unified GValue marshaller. https://bugzilla.gnome.org/show_bug.cgi?id=726999 --- gi/pygi-property.c | 9 +++++++++ gi/pygi-value.c | 26 ++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/gi/pygi-property.c b/gi/pygi-property.c index 9a6e0ea3..82811fb0 100644 --- a/gi/pygi-property.c +++ b/gi/pygi-property.c @@ -102,6 +102,7 @@ pygi_get_property_value (PyGObject *instance, GParamSpec *pspec) GIPropertyInfo *property_info = NULL; GValue value = { 0, }; PyObject *py_value = NULL; + GType fundamental; if (!(pspec->flags & G_PARAM_READABLE)) { PyErr_Format(PyExc_TypeError, "property %s is not readable", @@ -112,8 +113,16 @@ pygi_get_property_value (PyGObject *instance, GParamSpec *pspec) Py_BEGIN_ALLOW_THREADS; g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_object_get_property (instance->obj, pspec->name, &value); + fundamental = G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (&value)); Py_END_ALLOW_THREADS; + + /* Fast path basic types which don't need GI type info. */ + py_value = pygi_value_to_py_basic_type (&value, fundamental); + if (py_value) { + goto out; + } + /* Fast path which checks if this is a Python implemented Property. * TODO: Make it even faster by calling the Python getter implementation * directly. See: https://bugzilla.gnome.org/show_bug.cgi?id=723872 */ diff --git a/gi/pygi-value.c b/gi/pygi-value.c index c83ef5c9..0e6647d6 100644 --- a/gi/pygi-value.c +++ b/gi/pygi-value.c @@ -656,14 +656,12 @@ PyObject * pygi_value_to_py_basic_type (const GValue *value, GType fundamental) { switch (fundamental) { - case G_TYPE_CHAR: { - gint8 val = g_value_get_schar(value); - return PYGLIB_PyUnicode_FromStringAndSize((char *)&val, 1); - } - case G_TYPE_UCHAR: { - guint8 val = g_value_get_uchar(value); - return PYGLIB_PyBytes_FromStringAndSize((char *)&val, 1); - } + case G_TYPE_CHAR: + return PYGLIB_PyLong_FromLong (g_value_get_schar (value)); + + case G_TYPE_UCHAR: + return PYGLIB_PyLong_FromLong (g_value_get_uchar (value)); + case G_TYPE_BOOLEAN: { return PyBool_FromLong(g_value_get_boolean(value)); } @@ -844,6 +842,18 @@ pyg_value_as_pyobject (const GValue *value, gboolean copy_boxed) PyObject *pyobj; GType fundamental = G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)); + /* HACK: special case char and uchar to return PyBytes intstead of integers + * in the general case. Property access will skip this by calling + * pygi_value_to_py_basic_type() directly. + * See: https://bugzilla.gnome.org/show_bug.cgi?id=733893 */ + if (fundamental == G_TYPE_CHAR) { + gint8 val = g_value_get_schar(value); + return PYGLIB_PyUnicode_FromStringAndSize ((char *)&val, 1); + } else if (fundamental == G_TYPE_UCHAR) { + guint8 val = g_value_get_uchar(value); + return PYGLIB_PyBytes_FromStringAndSize ((char *)&val, 1); + } + pyobj = pygi_value_to_py_basic_type (value, fundamental); if (pyobj) { return pyobj; -- cgit v1.2.1