[pygobject] Fast path property access for basic types



commit 2601011e9eb3b5f391161313ed568e5c4b67c99a
Author: Simon Feltman <sfeltman src gnome org>
Date:   Fri Aug 8 23:58:17 2014 -0700

    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 9a6e0ea..82811fb 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 c83ef5c..0e6647d 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;


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