diff options
author | Sebastian Berg <sebastian@sipsolutions.net> | 2021-12-07 20:17:17 -0600 |
---|---|---|
committer | Sebastian Berg <sebastianb@nvidia.com> | 2023-01-17 18:40:44 +0100 |
commit | 60a858a372b14b73547baacf4a472eccfade1073 (patch) | |
tree | 1061a985383ad6ab2a8dc56f144ec25cfbff071e /numpy/core/numeric.py | |
parent | 9b6a7b4f874f5502112f36d485b12d92889eb808 (diff) | |
download | numpy-60a858a372b14b73547baacf4a472eccfade1073.tar.gz |
ENH: Improve array function overhead by using vectorcall
This moves dispatching for `__array_function__` into a C-wrapper. This
helps speed for multiple reasons:
* Avoids one additional dispatching function call to C
* Avoids the use of `*args, **kwargs` which is slower.
* For simple NumPy calls we can stay in the faster "vectorcall" world
This speeds up things generally a little, but can speed things up a lot
when keyword arguments are used on lightweight functions, for example::
np.can_cast(arr, dtype, casting="same_kind")
is more than twice as fast with this.
There is one alternative in principle to get best speed: We could inline
the "relevant argument"/dispatcher extraction. That changes behavior in
an acceptable but larger way (passes default arguments).
Unless the C-entry point seems unwanted, this should be a decent step
in the right direction even if we want to do that eventually, though.
Closes gh-20790
Closes gh-18547 (although not quite sure why)
Diffstat (limited to 'numpy/core/numeric.py')
-rw-r--r-- | numpy/core/numeric.py | 37 |
1 files changed, 8 insertions, 29 deletions
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py index 577f8e7cd..91e35c684 100644 --- a/numpy/core/numeric.py +++ b/numpy/core/numeric.py @@ -130,10 +130,6 @@ def zeros_like(a, dtype=None, order='K', subok=True, shape=None): return res -def _ones_dispatcher(shape, dtype=None, order=None, *, like=None): - return(like,) - - @set_array_function_like_doc @set_module('numpy') def ones(shape, dtype=None, order='C', *, like=None): @@ -187,16 +183,13 @@ def ones(shape, dtype=None, order='C', *, like=None): """ if like is not None: - return _ones_with_like(shape, dtype=dtype, order=order, like=like) + return _ones_with_like(like, shape, dtype=dtype, order=order) a = empty(shape, dtype, order) multiarray.copyto(a, 1, casting='unsafe') return a - -_ones_with_like = array_function_dispatch( - _ones_dispatcher -)(ones) +_ones_with_like = array_function_dispatch()(ones) def _ones_like_dispatcher(a, dtype=None, order=None, subok=None, shape=None): @@ -323,7 +316,7 @@ def full(shape, fill_value, dtype=None, order='C', *, like=None): """ if like is not None: - return _full_with_like(shape, fill_value, dtype=dtype, order=order, like=like) + return _full_with_like(like, shape, fill_value, dtype=dtype, order=order) if dtype is None: fill_value = asarray(fill_value) @@ -333,9 +326,7 @@ def full(shape, fill_value, dtype=None, order='C', *, like=None): return a -_full_with_like = array_function_dispatch( - _full_dispatcher -)(full) +_full_with_like = array_function_dispatch()(full) def _full_like_dispatcher(a, fill_value, dtype=None, order=None, subok=None, shape=None): @@ -1778,10 +1769,6 @@ def indices(dimensions, dtype=int, sparse=False): return res -def _fromfunction_dispatcher(function, shape, *, dtype=None, like=None, **kwargs): - return (like,) - - @set_array_function_like_doc @set_module('numpy') def fromfunction(function, shape, *, dtype=float, like=None, **kwargs): @@ -1847,15 +1834,13 @@ def fromfunction(function, shape, *, dtype=float, like=None, **kwargs): """ if like is not None: - return _fromfunction_with_like(function, shape, dtype=dtype, like=like, **kwargs) + return _fromfunction_with_like(like, function, shape, dtype=dtype, **kwargs) args = indices(shape, dtype=dtype) return function(*args, **kwargs) -_fromfunction_with_like = array_function_dispatch( - _fromfunction_dispatcher -)(fromfunction) +_fromfunction_with_like = array_function_dispatch()(fromfunction) def _frombuffer(buf, dtype, shape, order): @@ -2130,10 +2115,6 @@ def _maketup(descr, val): return tuple(res) -def _identity_dispatcher(n, dtype=None, *, like=None): - return (like,) - - @set_array_function_like_doc @set_module('numpy') def identity(n, dtype=None, *, like=None): @@ -2168,15 +2149,13 @@ def identity(n, dtype=None, *, like=None): """ if like is not None: - return _identity_with_like(n, dtype=dtype, like=like) + return _identity_with_like(like, n, dtype=dtype) from numpy import eye return eye(n, dtype=dtype, like=like) -_identity_with_like = array_function_dispatch( - _identity_dispatcher -)(identity) +_identity_with_like = array_function_dispatch()(identity) def _allclose_dispatcher(a, b, rtol=None, atol=None, equal_nan=None): |