-
Notifications
You must be signed in to change notification settings - Fork 6
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
smart read #49
Comments
Essentially, if you do many unstructured reads on a small number of chunks the difference is very large. I think if I generate a dataset using things like |
yup, sciserver works |
Here is an example
The difference here is actually not very large, but if you do the same operation repeatedly, it is going to be significant. |
I agree this is an ad hoc thing, and the majority of the function is not very frequently called. When I first started developing this, I remember reading one single entry from ECCO using xarray takes 2 seconds. This is either because the xarray code has improved, or because we were using netcdf at that point. |
I think you are showing something slightly different here. If you are sure that you can load the data, this is faster: da.values[indexes0, ...] But in da.data.vindex[indexes0, ...] # data return dask if chunked, numpy otherwise |
This is my benchmark: import oceanspy as ospy
import numpy as np
import xarray as xr
od = ospy.open_oceandataset.from_catalog("HYCOM")
da = od._ds.Eta.isel(time=slice(0, 5))
size = 100000
iy = np.random.randint(1251, size=size)
ix = np.random.randint(701, size=size)
it = np.random.randint(5, size=size)
indexers = {dim: xr.DataArray(indexes) for dim, indexes in zip(da.dims, (it, iy, ix))} _ = da.values # make sure there's no caching %%timeit
da.values[it, iy, ix]
%%timeit
da.isel(indexers).values
%%timeit
da.data.vindex[it, iy, ix].compute()
|
Here is the same benchmark removing the slicing of da performed in the previous one. import oceanspy as ospy
import numpy as np
import xarray as xr
od = ospy.open_oceandataset.from_catalog("HYCOM")
da = od._ds.Eta
size = 100000
iy = np.random.randint(1251, size=size)
ix = np.random.randint(701, size=size)
it = np.random.randint(5, size=size)
indexers = {dim: xr.DataArray(indexes) for dim, indexes in zip(da.dims, (it, iy, ix))} %%timeit
da.isel(indexers).values
%%timeit
da.data.vindex[it, iy, ix].compute()
|
For my purposes, there tend to be some locality of the data. For example, the velocities I read is going to be at the same time. So the indexes I am interested in tends to be on a few chunks. The problem for using values is that it may not be very easy to figure out how to slice. For example, for LLC 4320 data, each face is a chunk, but I want to read only from face 2 and 10 but not 3,4,5,6... Since most of the time is spend reading the data, figuring out which chunks to read is not too time consuming. If I only need to read a couple of chunks, it is faster than xarray (at least was). Again, I am not claiming this is anywhere near the best way to do it. I isolate the function so much is precisely because I would like to improve it in the future. |
ahhh, now I understand the goal of this function. %%timeit
smart_read(da, (it, iy, ix))
|
Got quite some improvement here #51. We might revisit some day. |
Ah, you merged quick. Final comments:
|
OK, I will change that.
I don't think there is anything that needs to be done about it here. But I will change that.
I didn't know you could just add dask.array as an dependency. I will try that.
Based on some rough bench marking, for a typical number of particles, 10^4- 10^7 (I tested 10^5) this is a good criterion to switch. |
Hi,
I'm surprised you had to code smart_read to have good performance.
I have a few tips, but before I would like to explore
xarray/dask/numpy
optimisations.Do you have a good MRE where
smart_read
makes the difference and that I can use to benchmark?The text was updated successfully, but these errors were encountered: