summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Feltman <sfeltman@src.gnome.org>2014-08-08 23:58:17 -0700
committerSimon Feltman <sfeltman@src.gnome.org>2014-08-17 22:31:19 -0700
commit2601011e9eb3b5f391161313ed568e5c4b67c99a (patch)
treedc7c4f68cf5094490dfe3a78224af769910bce0f
parent8f4b06f700ed79df32774fad8e2a2a922bfbfbe5 (diff)
downloadpygobject-2601011e9eb3b5f391161313ed568e5c4b67c99a.tar.gz
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
-rw-r--r--gi/pygi-property.c9
-rw-r--r--gi/pygi-value.c26
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;