diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2018-02-08 22:32:05 -0800 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2018-02-08 22:41:09 -0800 |
commit | ff2e1bc0976210076d309f1cee4323352017d1fd (patch) | |
tree | 7adc0832cf10adce7df15fe49a4ca143318a6374 | |
parent | 4cfac4067a27835de6b0ae204df0e8c91998c1f2 (diff) | |
download | numpy-ff2e1bc0976210076d309f1cee4323352017d1fd.tar.gz |
MAINT: Push no-op type promotion check further down
This does mean we do a redundant refcount change, but that's a small price to pay
-rw-r--r-- | numpy/core/src/multiarray/convert_datatype.c | 86 |
1 files changed, 33 insertions, 53 deletions
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c index 6ff381862..00cb07335 100644 --- a/numpy/core/src/multiarray/convert_datatype.c +++ b/numpy/core/src/multiarray/convert_datatype.c @@ -1002,6 +1002,17 @@ PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2) { int type_num1, type_num2, ret_type_num; + /* + * Fast path for identical dtypes. + * + * Non-native-byte-order types are converted to native ones below, so we + * can't quit early. + */ + if (type1 == type2 && PyArray_ISNBO(type1->byteorder)) { + Py_INCREF(type1); + return type1; + } + type_num1 = type1->type_num; type_num2 = type2->type_num; @@ -1296,6 +1307,8 @@ PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2) /* * Produces the smallest size and lowest kind type to which all * input types can be cast. + * + * Equivalent to functools.reduce(PyArray_PromoteTypes, types) */ NPY_NO_EXPORT PyArray_Descr * PyArray_PromoteTypeSequence(PyArray_Descr **types, npy_intp ntypes) @@ -1309,16 +1322,11 @@ PyArray_PromoteTypeSequence(PyArray_Descr **types, npy_intp ntypes) ret = types[0]; Py_INCREF(ret); for (i = 1; i < ntypes; ++i) { - PyArray_Descr *type = types[i]; - - /* Only call promote if the types aren't the same dtype */ - if (type != ret || !PyArray_ISNBO(type->byteorder)) { - PyArray_Descr *tmp = PyArray_PromoteTypes(type, ret); - Py_DECREF(ret); - ret = tmp; - if (ret == NULL) { - return NULL; - } + PyArray_Descr *tmp = PyArray_PromoteTypes(types[i], ret); + Py_DECREF(ret); + ret = tmp; + if (ret == NULL) { + return NULL; } } return ret; @@ -1698,7 +1706,7 @@ PyArray_ResultType(npy_intp narrs, PyArrayObject **arr, { npy_intp i; int use_min_scalar = 0; - PyArray_Descr *ret = NULL, *tmpret; + PyArray_Descr *ret = NULL; int ret_is_small_unsigned = 0; /* If there's just one type, pass it through */ @@ -1794,30 +1802,15 @@ PyArray_ResultType(npy_intp narrs, PyArrayObject **arr, ret_is_small_unsigned = tmp_is_small_unsigned; } else { -#if 0 - printf("promoting type "); - PyObject_Print(tmp, stdout, 0); - printf(" (%d) ", tmp_is_small_unsigned); - PyObject_Print(ret, stdout, 0); - printf(" (%d) ", ret_is_small_unsigned); - printf("\n"); -#endif - /* If they point to the same type, don't call promote */ - if (tmp == ret && PyArray_ISNBO(tmp->byteorder)) { - Py_DECREF(tmp); - } - else { - tmpret = promote_types(tmp, ret, tmp_is_small_unsigned, - ret_is_small_unsigned); - if (tmpret == NULL) { - Py_DECREF(tmp); - Py_DECREF(ret); - return NULL; - } - Py_DECREF(tmp); - Py_DECREF(ret); - ret = tmpret; + PyArray_Descr *tmpret = promote_types( + tmp, ret, tmp_is_small_unsigned, ret_is_small_unsigned); + Py_DECREF(tmp); + Py_DECREF(ret); + ret = tmpret; + if (ret == NULL) { + return NULL; } + ret_is_small_unsigned = tmp_is_small_unsigned && ret_is_small_unsigned; } @@ -1831,25 +1824,12 @@ PyArray_ResultType(npy_intp narrs, PyArrayObject **arr, Py_INCREF(ret); } else { - /* Only call promote if the types aren't the same dtype */ - if (tmp != ret || !PyArray_ISNBO(tmp->byteorder)) { - if (ret_is_small_unsigned) { - tmpret = promote_types(tmp, ret, 0, - ret_is_small_unsigned); - if (tmpret == NULL) { - Py_DECREF(tmp); - Py_DECREF(ret); - return NULL; - } - } - else { - tmpret = PyArray_PromoteTypes(tmp, ret); - } - Py_DECREF(ret); - ret = tmpret; - if (ret == NULL) { - return NULL; - } + PyArray_Descr *tmpret = promote_types( + tmp, ret, 0, ret_is_small_unsigned); + Py_DECREF(ret); + ret = tmpret; + if (ret == NULL) { + return NULL; } } } |