Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-01-07 08:33:30 +0300
committerCampbell Barton <ideasman42@gmail.com>2011-01-07 08:33:30 +0300
commit0f2089afa12832d48b9953d317ade4a12d3c5d93 (patch)
tree0666bd5d21a10447931b89500a5c96b01a9dff28 /source
parent5d74d65106937608de2833428f7b34979aca3c4b (diff)
py/rna api speedup for collection slicing in all cases, rather then having an exception for [:].
- avoid looping over the entire collection unless a negative index is used. - dont use the get index function for building the slice list, instead loop over the collection until the stop value.
Diffstat (limited to 'source')
-rw-r--r--source/blender/python/intern/bpy_rna.c98
1 files changed, 50 insertions, 48 deletions
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 74dcc811185..881d71d811f 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -93,7 +93,7 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item
#ifdef USE_MATHUTILS
#include "../generic/mathutils.h" /* so we can have mathutils callbacks */
-static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length);
+static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length);
static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_eul_order, short order_fallback);
/* bpyrna vector/euler/quat callbacks */
@@ -1470,43 +1470,45 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, cons
}
/* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
-static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, int start, int stop, int len)
+static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py_ssize_t start, Py_ssize_t stop)
{
- if(start == 0 && stop == len) {
- /* faster */
- return pyrna_prop_collection_values(self);
- }
- else {
- PointerRNA *ptr= &self->ptr;
- PropertyRNA *prop= self->prop;
+ int count= 0;
- PointerRNA newptr;
- PyObject *list = PyList_New(stop - start);
- int count;
+ PyObject *list= PyList_New(0);
+ PyObject *item;
- start = MIN2(start,stop); /* values are clamped from */
+ /* first loop up-until the start */
+ CollectionPropertyIterator rna_macro_iter;
+ for(RNA_property_collection_begin(&self->ptr, self->prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
+ /* PointerRNA itemptr= rna_macro_iter.ptr; */
+ if(count == start) {
+ break;
+ }
+ count++;
+ }
- for(count = start; count < stop; count++) {
- if(RNA_property_collection_lookup_int(ptr, prop, count - start, &newptr)) {
- PyList_SET_ITEM(list, count - start, pyrna_struct_CreatePyObject(&newptr));
- }
- else {
- Py_DECREF(list);
+ /* add items until stop */
+ for(; rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) {
+ item= pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
+ PyList_Append(list, item);
+ Py_DECREF(item);
- PyErr_Format(PyExc_RuntimeError, "bpy_prop_collection[%d:%d]: internal error RNA_property_collection_lookup_int(...) failed with array index in range.", start, stop);
- return NULL;
- }
+ count++;
+ if(count == stop) {
+ break;
}
-
- return list;
}
+
+ RNA_property_collection_end(&rna_macro_iter);
+
+ return list;
}
/* TODO - dimensions
* note: could also use pyrna_prop_array_to_py_index(self, count) in a loop but its a lot slower
* since at the moment it reads (and even allocates) the entire array for each index.
*/
-static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int start, int stop, int length)
+static PyObject *pyrna_prop_array_subscript_slice(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t length)
{
int count, totdim;
@@ -1592,30 +1594,38 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
return pyrna_prop_collection_subscript_int(self, i);
}
else if (PySlice_Check(key)) {
+ PySliceObject *key_slice= (PySliceObject *)key;
Py_ssize_t step= 1;
- if(((PySliceObject *)key)->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
+ if(key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
}
else if (step != 1) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
return NULL;
}
- else if(((PySliceObject *)key)->start == Py_None && ((PySliceObject *)key)->stop == Py_None) {
- return pyrna_prop_collection_values(self);
+ else if(key_slice->start == Py_None && key_slice->stop == Py_None) {
+ return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
}
else {
- int len= RNA_property_collection_length(&self->ptr, self->prop);
- Py_ssize_t start, stop, slicelength;
+ Py_ssize_t start= 0, stop= PY_SSIZE_T_MAX;
- if (PySlice_GetIndicesEx((PySliceObject*)key, len, &start, &stop, &step, &slicelength) < 0)
- return NULL;
+ /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
+ if(key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
+ if(key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) return NULL;
- if (slicelength <= 0) {
+ if(start < 0 || stop < 0) {
+ /* only get the length for negative values */
+ Py_ssize_t len= (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
+ if(start < 0) start += len;
+ if(stop < 0) start += len;
+ }
+
+ if (stop - start <= 0) {
return PyList_New(0);
}
else {
- return pyrna_prop_collection_subscript_slice(self, start, stop, len);
+ return pyrna_prop_collection_subscript_slice(self, start, stop);
}
}
}
@@ -1638,17 +1648,18 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject
}
else if (PySlice_Check(key)) {
Py_ssize_t step= 1;
+ PySliceObject *key_slice= (PySliceObject *)key;
- if(((PySliceObject *)key)->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
+ if(key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
}
else if (step != 1) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
return NULL;
}
- else if(((PySliceObject *)key)->start == Py_None && ((PySliceObject *)key)->stop == Py_None) {
+ else if(key_slice->start == Py_None && key_slice->stop == Py_None) {
/* note, no significant advantage with optimizing [:] slice as with collections but include here for consistency with collection slice func */
- int len= pyrna_prop_array_length(self);
+ Py_ssize_t len= (Py_ssize_t)pyrna_prop_array_length(self);
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
}
else {
@@ -3153,17 +3164,8 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self)
{
- PyObject *ret= PyList_New(0);
- PyObject *item;
-
- RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
- item = pyrna_struct_CreatePyObject(&itemptr);
- PyList_Append(ret, item);
- Py_DECREF(item);
- }
- RNA_PROP_END;
-
- return ret;
+ /* re-use slice*/
+ return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
}
static char pyrna_struct_get_doc[] =