-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
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
np.isclose is slow #16160
Comments
NumPy functions are intended to be run on NumPy arrays - in this case, you are passing in scalar values which are converted to arrays under-the-hood by Note however that >>> rg = np.random.default_rng()
>>> a, b = rg.random(1000), rg.random(1000)
>>> %timeit np.isclose(0.5, 0, atol=1e-4) # Original example
29.4 µs ± 1.32 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit np.isclose(a, b, atol=1e-4) # Same operation, 1000 elements
29.8 µs ± 499 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) |
@rossbar Thanks for pointing out that However, for simple use case with >>> rg = np.random.default_rng()
>>> a, b = rg.random(1000), rg.random(1000)
>>> %timeit np.isclose(a,b, atol=1e-4)
38.7 µs ± 2.98 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit np.abs(a-b) <= 1e-4
3.36 µs ± 52.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) |
Good point - if you take a look at how It may be worthwhile to see if things couldn't be reorganized so that those checks are moved further down in a conditional branch to try to reduce the overhead for the simple case. |
After doing some basic profiling, it is found that
We could probably replace the two calls
|
Another slowness probably comes from this line with
|
The function FWIW, I just ran the full test suite without the |
Are you sure that's |
That's a great finding. It seems that we could speed this up by only adding |
Apologies, I missed the |
Hehe, one of the least used and stranger features... But, its not exposed for reductions:
It feels a bit silly that it includes the buffersize, although you could use @Hoiy I think we will accept PRs for some of the things you found, but there is probably only so much to be done, considering that this calls many functions all of which incur a significant overhead since they are written to be fast for arrays and not scalars. (and in general any function call has a fairly significant overhead). |
Since my last comment was a long time ago and mentioned |
Retesting with NumPy 2.0 after a long time. import numpy as np
rg = np.random.default_rng()
a, b = rg.random(1000), rg.random(1000)
%timeit np.isclose(a,b)
# 20.7 μs ± 1.44 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit np.abs(a-b) <= 1.e-8
# 4.07 μs ± 338 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
%timeit np.abs(a-b) <= 1.e-8 + 1.e-5 * np.abs(b)
# 7.87 μs ± 175 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) The time difference between np.isclose() and np.abs() improved from 38.7 : 3.36 to 20.7 : 4.07 (about 5.08 times slower) . I realized that I should be doing apple to apple comparison involving The slowness of np.isclose() now comes from
Removing these would improve np.isclose() to about 12.4 μs (I know these lines exist for a reason, just stating the observation). |
np.isclose is very slow compared with math.isclose
Reproducing code example:
Error message:
Numpy/Python version information:
1.17.4 3.7.5 (default, Dec 9 2019, 22:42:26)
[Clang 11.0.0 (clang-1100.0.33.12)]
The text was updated successfully, but these errors were encountered: