Optimize PySequence_Fast usage
Access arrays directly, avoiding type-check every time.
This commit is contained in:
@@ -3766,6 +3766,7 @@ void *BPy_BMElem_PySeq_As_Array_FAST(
|
|||||||
const char *error_prefix)
|
const char *error_prefix)
|
||||||
{
|
{
|
||||||
BMesh *bm = (r_bm && *r_bm) ? *r_bm : NULL;
|
BMesh *bm = (r_bm && *r_bm) ? *r_bm : NULL;
|
||||||
|
PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
|
||||||
const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
|
const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
@@ -3785,7 +3786,7 @@ void *BPy_BMElem_PySeq_As_Array_FAST(
|
|||||||
alloc = PyMem_MALLOC(seq_len * sizeof(BPy_BMElem **));
|
alloc = PyMem_MALLOC(seq_len * sizeof(BPy_BMElem **));
|
||||||
|
|
||||||
for (i = 0; i < seq_len; i++) {
|
for (i = 0; i < seq_len; i++) {
|
||||||
item = (BPy_BMElem *)PySequence_Fast_GET_ITEM(seq_fast, i);
|
item = (BPy_BMElem *)seq_fast_items[i];
|
||||||
|
|
||||||
if (!BPy_BMElem_CheckHType(Py_TYPE(item), htype)) {
|
if (!BPy_BMElem_CheckHType(Py_TYPE(item), htype)) {
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
@@ -299,12 +299,14 @@ static PyObject *BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item)
|
|||||||
/* returns NULL on success, error string on failure */
|
/* returns NULL on success, error string on failure */
|
||||||
static char idp_sequence_type(PyObject *seq_fast)
|
static char idp_sequence_type(PyObject *seq_fast)
|
||||||
{
|
{
|
||||||
|
PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
char type = IDP_INT;
|
char type = IDP_INT;
|
||||||
|
|
||||||
Py_ssize_t i, len = PySequence_Fast_GET_SIZE(seq_fast);
|
Py_ssize_t i, len = PySequence_Fast_GET_SIZE(seq_fast);
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
item = PySequence_Fast_GET_ITEM(seq_fast, i);
|
item = seq_fast_items[i];
|
||||||
if (PyFloat_Check(item)) {
|
if (PyFloat_Check(item)) {
|
||||||
if (type == IDP_IDPARRAY) { /* mixed dict/int */
|
if (type == IDP_IDPARRAY) { /* mixed dict/int */
|
||||||
return -1;
|
return -1;
|
||||||
@@ -396,14 +398,17 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group,
|
|||||||
//prop->subtype = IDP_STRING_SUB_BYTE;
|
//prop->subtype = IDP_STRING_SUB_BYTE;
|
||||||
}
|
}
|
||||||
else if (PySequence_Check(ob)) {
|
else if (PySequence_Check(ob)) {
|
||||||
PyObject *ob_seq_fast = PySequence_Fast(ob, "py -> idprop");
|
PyObject *ob_seq_fast;
|
||||||
|
PyObject **ob_seq_fast_items;
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (ob_seq_fast == NULL) {
|
if (!(ob_seq_fast = PySequence_Fast(ob, "py -> idprop"))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ob_seq_fast_items = PySequence_Fast_ITEMS(ob_seq_fast);
|
||||||
|
|
||||||
if ((val.array.type = idp_sequence_type(ob_seq_fast)) == (char)-1) {
|
if ((val.array.type = idp_sequence_type(ob_seq_fast)) == (char)-1) {
|
||||||
Py_DECREF(ob_seq_fast);
|
Py_DECREF(ob_seq_fast);
|
||||||
PyErr_SetString(PyExc_TypeError, "only floats, ints and dicts are allowed in ID property arrays");
|
PyErr_SetString(PyExc_TypeError, "only floats, ints and dicts are allowed in ID property arrays");
|
||||||
@@ -424,7 +429,7 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group,
|
|||||||
prop = IDP_New(IDP_ARRAY, &val, name);
|
prop = IDP_New(IDP_ARRAY, &val, name);
|
||||||
prop_data = IDP_Array(prop);
|
prop_data = IDP_Array(prop);
|
||||||
for (i = 0; i < val.array.len; i++) {
|
for (i = 0; i < val.array.len; i++) {
|
||||||
item = PySequence_Fast_GET_ITEM(ob_seq_fast, i);
|
item = ob_seq_fast_items[i];
|
||||||
if (((prop_data[i] = PyFloat_AsDouble(item)) == -1.0) && PyErr_Occurred()) {
|
if (((prop_data[i] = PyFloat_AsDouble(item)) == -1.0) && PyErr_Occurred()) {
|
||||||
Py_DECREF(ob_seq_fast);
|
Py_DECREF(ob_seq_fast);
|
||||||
return false;
|
return false;
|
||||||
@@ -438,7 +443,7 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group,
|
|||||||
prop = IDP_New(IDP_ARRAY, &val, name);
|
prop = IDP_New(IDP_ARRAY, &val, name);
|
||||||
prop_data = IDP_Array(prop);
|
prop_data = IDP_Array(prop);
|
||||||
for (i = 0; i < val.array.len; i++) {
|
for (i = 0; i < val.array.len; i++) {
|
||||||
item = PySequence_Fast_GET_ITEM(ob_seq_fast, i);
|
item = ob_seq_fast_items[i];
|
||||||
if (((prop_data[i] = _PyLong_AsInt(item)) == -1) && PyErr_Occurred()) {
|
if (((prop_data[i] = _PyLong_AsInt(item)) == -1) && PyErr_Occurred()) {
|
||||||
Py_DECREF(ob_seq_fast);
|
Py_DECREF(ob_seq_fast);
|
||||||
return false;
|
return false;
|
||||||
@@ -450,7 +455,7 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group,
|
|||||||
{
|
{
|
||||||
prop = IDP_NewIDPArray(name);
|
prop = IDP_NewIDPArray(name);
|
||||||
for (i = 0; i < val.array.len; i++) {
|
for (i = 0; i < val.array.len; i++) {
|
||||||
item = PySequence_Fast_GET_ITEM(ob_seq_fast, i);
|
item = ob_seq_fast_items[i];
|
||||||
|
|
||||||
if (BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item) == false) {
|
if (BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item) == false) {
|
||||||
Py_DECREF(ob_seq_fast);
|
Py_DECREF(ob_seq_fast);
|
||||||
|
@@ -53,6 +53,7 @@ int PyC_AsArray_FAST(
|
|||||||
const PyTypeObject *type, const bool is_double, const char *error_prefix)
|
const PyTypeObject *type, const bool is_double, const char *error_prefix)
|
||||||
{
|
{
|
||||||
const Py_ssize_t value_len = PySequence_Fast_GET_SIZE(value_fast);
|
const Py_ssize_t value_len = PySequence_Fast_GET_SIZE(value_fast);
|
||||||
|
PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
BLI_assert(PyList_Check(value_fast) || PyTuple_Check(value_fast));
|
BLI_assert(PyList_Check(value_fast) || PyTuple_Check(value_fast));
|
||||||
@@ -69,13 +70,13 @@ int PyC_AsArray_FAST(
|
|||||||
if (is_double) {
|
if (is_double) {
|
||||||
double *array_double = array;
|
double *array_double = array;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
array_double[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
|
array_double[i] = PyFloat_AsDouble(value_fast_items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float *array_float = array;
|
float *array_float = array;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
array_float[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
|
array_float[i] = PyFloat_AsDouble(value_fast_items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,13 +84,13 @@ int PyC_AsArray_FAST(
|
|||||||
/* could use is_double for 'long int' but no use now */
|
/* could use is_double for 'long int' but no use now */
|
||||||
int *array_int = array;
|
int *array_int = array;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
array_int[i] = PyLong_AsLong(PySequence_Fast_GET_ITEM(value_fast, i));
|
array_int[i] = PyLong_AsLong(value_fast_items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == &PyBool_Type) {
|
else if (type == &PyBool_Type) {
|
||||||
int *array_bool = array;
|
int *array_bool = array;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
array_bool[i] = (PyLong_AsLong(PySequence_Fast_GET_ITEM(value_fast, i)) != 0);
|
array_bool[i] = (PyLong_AsLong(value_fast_items[i]) != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -742,9 +742,11 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int len = PySequence_Fast_GET_SIZE(seq_fast);
|
int len = PySequence_Fast_GET_SIZE(seq_fast);
|
||||||
|
PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
PyObject *list_item = PySequence_Fast_GET_ITEM(seq_fast, i);
|
PyObject *list_item = seq_fast_items[i];
|
||||||
|
|
||||||
if (BPy_StructRNA_Check(list_item)) {
|
if (BPy_StructRNA_Check(list_item)) {
|
||||||
#if 0
|
#if 0
|
||||||
|
@@ -1319,6 +1319,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
|
|||||||
EnumPropertyItem *items;
|
EnumPropertyItem *items;
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
|
const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
|
||||||
|
PyObject **seq_fast_items = PySequence_Fast_ITEMS(seq_fast);
|
||||||
Py_ssize_t totbuf = 0;
|
Py_ssize_t totbuf = 0;
|
||||||
int i;
|
int i;
|
||||||
short def_used = 0;
|
short def_used = 0;
|
||||||
@@ -1366,7 +1367,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
|
|||||||
Py_ssize_t name_str_size;
|
Py_ssize_t name_str_size;
|
||||||
Py_ssize_t desc_str_size;
|
Py_ssize_t desc_str_size;
|
||||||
|
|
||||||
item = PySequence_Fast_GET_ITEM(seq_fast, i);
|
item = seq_fast_items[i];
|
||||||
|
|
||||||
if ((PyTuple_CheckExact(item)) &&
|
if ((PyTuple_CheckExact(item)) &&
|
||||||
(item_size = PyTuple_GET_SIZE(item)) &&
|
(item_size = PyTuple_GET_SIZE(item)) &&
|
||||||
|
@@ -2637,6 +2637,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop,
|
|||||||
int start, int stop, int length, PyObject *value_orig)
|
int start, int stop, int length, PyObject *value_orig)
|
||||||
{
|
{
|
||||||
PyObject *value;
|
PyObject *value;
|
||||||
|
PyObject **value_items;
|
||||||
int count;
|
int count;
|
||||||
void *values_alloc = NULL;
|
void *values_alloc = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -2658,6 +2659,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value_items = PySequence_Fast_ITEMS(value);
|
||||||
switch (RNA_property_type(prop)) {
|
switch (RNA_property_type(prop)) {
|
||||||
case PROP_FLOAT:
|
case PROP_FLOAT:
|
||||||
{
|
{
|
||||||
@@ -2673,7 +2675,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop,
|
|||||||
RNA_property_float_get_array(ptr, prop, values);
|
RNA_property_float_get_array(ptr, prop, values);
|
||||||
|
|
||||||
for (count = start; count < stop; count++) {
|
for (count = start; count < stop; count++) {
|
||||||
fval = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value, count - start));
|
fval = PyFloat_AsDouble(value_items[count - start]);
|
||||||
CLAMP(fval, min, max);
|
CLAMP(fval, min, max);
|
||||||
values[count] = fval;
|
values[count] = fval;
|
||||||
}
|
}
|
||||||
@@ -2693,7 +2695,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop,
|
|||||||
RNA_property_boolean_get_array(ptr, prop, values);
|
RNA_property_boolean_get_array(ptr, prop, values);
|
||||||
|
|
||||||
for (count = start; count < stop; count++)
|
for (count = start; count < stop; count++)
|
||||||
values[count] = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count - start));
|
values[count] = PyLong_AsLong(value_items[count - start]);
|
||||||
|
|
||||||
if (PyErr_Occurred()) ret = -1;
|
if (PyErr_Occurred()) ret = -1;
|
||||||
else RNA_property_boolean_set_array(ptr, prop, values);
|
else RNA_property_boolean_set_array(ptr, prop, values);
|
||||||
@@ -2714,7 +2716,7 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop,
|
|||||||
RNA_property_int_get_array(ptr, prop, values);
|
RNA_property_int_get_array(ptr, prop, values);
|
||||||
|
|
||||||
for (count = start; count < stop; count++) {
|
for (count = start; count < stop; count++) {
|
||||||
ival = PyLong_AsLong(PySequence_Fast_GET_ITEM(value, count - start));
|
ival = PyLong_AsLong(value_items[count - start]);
|
||||||
CLAMP(ival, min, max);
|
CLAMP(ival, min, max);
|
||||||
values[count] = ival;
|
values[count] = ival;
|
||||||
}
|
}
|
||||||
|
@@ -57,20 +57,22 @@ static int mathutils_array_parse_fast(float *array,
|
|||||||
const char *error_prefix)
|
const char *error_prefix)
|
||||||
{
|
{
|
||||||
PyObject *item;
|
PyObject *item;
|
||||||
|
PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = size;
|
i = size;
|
||||||
do {
|
do {
|
||||||
i--;
|
i--;
|
||||||
if (((array[i] = PyFloat_AsDouble((item = PySequence_Fast_GET_ITEM(value_fast, i)))) == -1.0f) &&
|
if (((array[i] = PyFloat_AsDouble((item = value_fast_items[i]))) == -1.0f) &&
|
||||||
PyErr_Occurred())
|
PyErr_Occurred())
|
||||||
{
|
{
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"%.200s: sequence index %d expected a number, "
|
"%.200s: sequence index %d expected a number, "
|
||||||
"found '%.200s' type, ",
|
"found '%.200s' type, ",
|
||||||
error_prefix, i, Py_TYPE(item)->tp_name);
|
error_prefix, i, Py_TYPE(item)->tp_name);
|
||||||
return -1;
|
size = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} while (i);
|
} while (i);
|
||||||
|
|
||||||
@@ -261,7 +263,7 @@ int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, c
|
|||||||
/* parse an array of vectors */
|
/* parse an array of vectors */
|
||||||
int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value, const char *error_prefix)
|
int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value, const char *error_prefix)
|
||||||
{
|
{
|
||||||
PyObject *value_fast = NULL;
|
PyObject *value_fast;
|
||||||
const int array_dim_flag = array_dim;
|
const int array_dim_flag = array_dim;
|
||||||
int i, size;
|
int i, size;
|
||||||
|
|
||||||
@@ -274,6 +276,7 @@ int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value,
|
|||||||
size = PySequence_Fast_GET_SIZE(value_fast);
|
size = PySequence_Fast_GET_SIZE(value_fast);
|
||||||
|
|
||||||
if (size != 0) {
|
if (size != 0) {
|
||||||
|
PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
|
||||||
float *fp;
|
float *fp;
|
||||||
|
|
||||||
array_dim &= ~MU_ARRAY_FLAGS;
|
array_dim &= ~MU_ARRAY_FLAGS;
|
||||||
@@ -281,7 +284,7 @@ int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value,
|
|||||||
fp = *array = PyMem_Malloc(size * array_dim * sizeof(float));
|
fp = *array = PyMem_Malloc(size * array_dim * sizeof(float));
|
||||||
|
|
||||||
for (i = 0; i < size; i++, fp += array_dim) {
|
for (i = 0; i < size; i++, fp += array_dim) {
|
||||||
PyObject *item = PySequence_Fast_GET_ITEM(value, i);
|
PyObject *item = value_fast_items[i];
|
||||||
|
|
||||||
if (mathutils_array_parse(fp, array_dim, array_dim_flag, item, error_prefix) == -1) {
|
if (mathutils_array_parse(fp, array_dim, array_dim_flag, item, error_prefix) == -1) {
|
||||||
PyMem_Free(*array);
|
PyMem_Free(*array);
|
||||||
|
@@ -2188,7 +2188,7 @@ static PyObject *Matrix_slice(MatrixObject *self, int begin, int end)
|
|||||||
* sequence slice (set)*/
|
* sequence slice (set)*/
|
||||||
static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value)
|
static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value)
|
||||||
{
|
{
|
||||||
PyObject *value_fast = NULL;
|
PyObject *value_fast;
|
||||||
|
|
||||||
if (BaseMath_ReadCallback_ForWrite(self) == -1)
|
if (BaseMath_ReadCallback_ForWrite(self) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -2203,6 +2203,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
|
||||||
const int size = end - begin;
|
const int size = end - begin;
|
||||||
int row, col;
|
int row, col;
|
||||||
float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
|
float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
|
||||||
@@ -2221,7 +2222,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
|
|||||||
/* parse sub items */
|
/* parse sub items */
|
||||||
for (row = begin; row < end; row++) {
|
for (row = begin; row < end; row++) {
|
||||||
/* parse each sub sequence */
|
/* parse each sub sequence */
|
||||||
PyObject *item = PySequence_Fast_GET_ITEM(value_fast, row - begin);
|
PyObject *item = value_fast_items[row - begin];
|
||||||
|
|
||||||
if (mathutils_array_parse(vec, self->num_col, self->num_col, item,
|
if (mathutils_array_parse(vec, self->num_col, self->num_col, item,
|
||||||
"matrix[begin:end] = value assignment") == -1)
|
"matrix[begin:end] = value assignment") == -1)
|
||||||
|
Reference in New Issue
Block a user