[Bf-blender-cvs] [9060bd8] tmp-id-users: Avoid re-creating a pyobject for each and every ID just to check dict key.

Bastien Montagne noreply at git.blender.org
Wed Jan 6 16:18:23 CET 2016


Commit: 9060bd863e7134b5e3398cc1c021f172184ddc9e
Author: Bastien Montagne
Date:   Tue Jan 5 19:23:47 2016 +0100
Branches: tmp-id-users
https://developer.blender.org/rB9060bd863e7134b5e3398cc1c021f172184ddc9e

Avoid re-creating a pyobject for each and every ID just to check dict key.

Nice hack suggested by Campbell. :)

===================================================================

M	source/blender/python/intern/bpy_data.c

===================================================================

diff --git a/source/blender/python/intern/bpy_data.c b/source/blender/python/intern/bpy_data.c
index d56d4ef..46215ae 100644
--- a/source/blender/python/intern/bpy_data.c
+++ b/source/blender/python/intern/bpy_data.c
@@ -54,8 +54,11 @@
 #include "bpy_rna.h"
 
 typedef struct IDUserMapData {
+	PyObject *py_id_key;
+
 	ID *id_curr;
 	PyObject *py_id_curr;
+
 	PyObject *user_map;
 	bool is_restricted;
 } IDUserMapData;
@@ -65,11 +68,13 @@ static bool foreach_libblock_id_user_map_callback(void *user_data, ID **id_p, in
 	IDUserMapData *data = user_data;
 
 	if (*id_p) {
-		PyObject *key = pyrna_id_CreatePyObject(*id_p);
 		PyObject *set;
 
+		/* Only stuff used by pyrna_struct_hash(). */
+		((BPy_StructRNA *)data->py_id_key)->ptr.data = *id_p;
+
 		if (data->is_restricted) {
-			if ((set = PyDict_GetItem(data->user_map, key))) {
+			if ((set = PyDict_GetItem(data->user_map, data->py_id_key))) {
 				if (data->py_id_curr == NULL) {
 					data->py_id_curr = pyrna_id_CreatePyObject(data->id_curr);
 				}
@@ -77,10 +82,13 @@ static bool foreach_libblock_id_user_map_callback(void *user_data, ID **id_p, in
 			}
 		}
 		else {
-			if ((set = PyDict_GetItem(data->user_map, key)) == NULL) {
+			if ((set = PyDict_GetItem(data->user_map, data->py_id_key)) == NULL) {
+				/* Cannot use our placeholder key here! */
+				PyObject *key = pyrna_id_CreatePyObject(data->id_curr);
 				set = PySet_New(NULL);
 				PyDict_SetItem(data->user_map, key, set);
 				Py_DECREF(set);
+				Py_DECREF(key);
 			}
 			if (data->py_id_curr == NULL) {
 				data->py_id_curr = pyrna_id_CreatePyObject(data->id_curr);
@@ -155,15 +163,24 @@ static PyObject *bpy_user_map(PyObject *UNUSED(self), PyObject *args)
 
 	while (lb_idx--) {
 		for (ID *id = lb_array[lb_idx]->first; id; id = id->next) {
+			/* One-time init, ID is just used as placeholder here, we abuse this in iterator callback
+			 * to avoid having to rebuild a complete bpyrna object each time for the key searching
+			 * (where only ID pointer value is used). */
+			if (data_cb.py_id_key == NULL) {
+				data_cb.py_id_key = pyrna_id_CreatePyObject(id);
+			}
+
 			data_cb.id_curr = id;
-			data_cb.py_id_curr = NULL;
 			BKE_library_foreach_ID_link(id, foreach_libblock_id_user_map_callback, &data_cb, IDWALK_NOP);
 			if (data_cb.py_id_curr) {
 				Py_DECREF(data_cb.py_id_curr);
+				data_cb.py_id_curr = NULL;
 			}
 		}
 	}
 
+	Py_XDECREF(data_cb.py_id_key);
+
 	return user_map;
 }




More information about the Bf-blender-cvs mailing list