8000 MAINT: Speed up normalize_axis_tuple by about 30% by mhvk · Pull Request #11518 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

MAINT: Speed up normalize_axis_tuple by about 30% #11518

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 9, 2018

Conversation

mhvk
Copy link
Contributor
@mhvk mhvk commented Jul 6, 2018

This is used in np.moveaxis, which is relatively slow. Timings change as follows:

import numpy as np
from numpy.core.numeric import normalize_axis_tuple
%timeit normalize_axis_tuple([0, 1, 2], 4, 'parrot')
a = np.zeros((10,20,30))
%timeit np.moveaxis(a, [0,1,2], [2,1,0])
100000 loops, best of 3: 5.56 µs per loop -> 4.17 µs

Should add that I'm not really all that happy with the present solution, but I cannot think of a better one that wouldn't either impact the iterable or the scalar case.

This is used in `np.moveaxis`, which is relatively slow.
Timings change as follows:
```
import numpy as np
from numpy.core.numeric import normalize_axis_tuple
%timeit normalize_axis_tuple([0, 1, 2], 4, 'parrot')
a = np.zeros((10,20,30))
%timeit np.moveaxis(a, [0,1,2], [2,1,0])
100000 loops, best of 3: 5.56 µs per loop -> 4.17 µs
```
axis = tuple(axis)
axis = tuple(normalize_axis_index(ax, ndim, argname) for ax in axis)
# Speed-up most common cases.
if not isinstance(axis, (list, tuple)):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be more correct to check type(axis) in (list, tuple), since subclasses might override __index__.

I was tempted to change it to just type(axis) is tuple, to encourage people to use tuple rather than list axis arguments....

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if someone subclasses list or tuple, one should reasonably expect that the object can be iterated over, not also treated as an integer! (I'd actually prefer to just test for something being iterable, but things like np.iterable are way slower than the isinstance check.)

As for tuple - I can at least change the order!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reasonable or not, I'd prefer that we don't introduce an unnecessary behavior change now.

type(axis) in (tuple, list) sounds like a good approach to me

except TypeError:
pass
# Going via an iterator directly is slower than via list comprehension.
axis = tuple([normalize_axis_index(ax, ndim, argname) for ax in axis])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this is the case...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think list comprehension is special-cased, not constructing an iterator but an actual for-loop with known size.

@mhvk
Copy link
Contributor Author
mhvk commented Jul 7, 2018

@eric-wieser - since you wrote the function, maybe it is easiest for you to just make any changes you want? I don't really like what I have here but don't have the time to think of something better.

@eric-wieser
Copy link
Member

Updated in place. I think I only extracted the function from its call site, rather than inventing it

@mhvk
Copy link
Contributor Author
mhvk commented Jul 9, 2018

OK, let's get this in - it is a speed improvement even if not super elegant.

@mhvk mhvk merged commit a52634d into numpy:master Jul 9, 2018
@mhvk mhvk deleted the normalize-axis-tuple-speedup branch July 9, 2018 04:13
@eric-wieser
Copy link
Member

Thanks for identifying a slowdown here - I'll be curious to see the benchmarks when they update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0