Skip to content

Commit 6511b96

Browse files
committed
Updated perf test to match README.
1 parent f78b878 commit 6511b96

1 file changed

Lines changed: 40 additions & 19 deletions

File tree

perf_tests/era5_temp_profile.py

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
#!/usr/bin/env python3
22
"""Surface and global-atmospheric temperatures on 2020-01-01, in SQL.
33
4-
Two queries against ARCO-ERA5 on the morning of January 1, 2020:
4+
Three queries against ARCO-ERA5 on the morning of January 1, 2020:
55
66
* **Surface (local).** Average 2m-temperature over a small grid covering the
77
New York City area for the first six hours.
88
* **Atmosphere (global).** Average temperature per pressure level, computed
99
over the entire planet for the same six hours — a classic atmospheric
1010
temperature profile (surface around 1000 hPa is warmest, tropopause near
1111
100 hPa is coldest).
12+
* **Surface (global, gridded).** Average 2m-temperature per (lat, lon) cell
13+
for the same six hours, returned as an xarray Dataset.
1214
13-
Both queries express their filters entirely in SQL: ``xr.open_zarr`` is given
14-
a single calendar year and no spatial slicing. The library's table provider
15-
prunes time partitions for ``WHERE time …`` filters, and pushes ``WHERE
15+
All filters live in SQL: the dataset is opened with no time or spatial
16+
slicing on the xarray side. The library's table provider prunes time
17+
partitions for ``WHERE time …`` filters, and pushes ``WHERE
1618
latitude/longitude …`` down to dimension columns.
1719
1820
ARCO-ERA5's atmospheric variables are stored in native Zarr chunks of shape
1921
``(1, 37, 721, 1440)`` — about 150 MB per hour. We align Dask chunks to that
20-
shape with ``chunks={'time': 1}`` so chunks fetch from GCS concurrently. The
21-
global atmospheric query scans ~230M rows after pruning.
22+
shape with ``chunks=dict(time=1)`` so chunks fetch from GCS concurrently.
2223
2324
The Zarr is read anonymously from the public GCS bucket — no auth required.
2425
"""
@@ -34,27 +35,29 @@
3435

3536

3637
def main() -> None:
37-
full = xr.open_zarr(URL, chunks=None, storage_options={"token": "anon"})
38-
39-
# Open a full calendar year — all 273 variables. No spatial slicing on
40-
# the xarray side; SQL WHERE clauses below express the filters.
41-
#
42-
# Heads up: the library pushes column projection down to Zarr, so SELECT
43-
# only fetches what you ask for — but `SELECT * FROM era5.surface` would
44-
# try to read every variable across the year (terabytes from GCS).
45-
# Always SELECT specific columns.
46-
ds = full.sel(time="2020").chunk({"time": 1})
38+
# Open the full ARCO-ERA5 archive — all 273 variables since 1940. No
39+
# time or spatial slicing on the xarray side; SQL WHERE clauses below
40+
# express the filters. Turning dask off (chunks=None) skips task-graph
41+
# construction at open time.
42+
ds = xr.open_zarr(URL, chunks=None, storage_options={"token": "anon"})
4743
print(
48-
"ARCO-ERA5 opened: year 2020, "
44+
"ARCO-ERA5 opened: "
4945
f"{ds.sizes['time']:,} hourly time steps, "
50-
f"{len(ds.data_vars)} variables (no spatial pre-slicing)."
46+
f"{len(ds.data_vars)} variables (no pre-slicing)."
5147
)
5248

49+
# Heads up: ARCO-ERA5 has 262 surface + 11 atmospheric variables. The
50+
# library pushes column projection down to Zarr, so SELECT only fetches
51+
# what you ask for — but `SELECT * FROM era5.surface` would try to pull
52+
# every variable across the archive (terabytes from GCS).
53+
# ---> Always SELECT specific columns. <---
5354
ctx = xql.XarrayContext()
5455
t0 = time.perf_counter()
56+
# Make sure to pass `chunks`!
5557
ctx.from_dataset(
5658
"era5",
5759
ds,
60+
chunks=dict(time=1),
5861
table_names={
5962
("time", "latitude", "longitude"): "surface",
6063
("time", "level", "latitude", "longitude"): "atmosphere",
@@ -94,7 +97,25 @@ def main() -> None:
9497
"""
9598
).to_pandas()
9699
print(profile.to_string(index=False))
97-
print(f" ({time.perf_counter() - t0:.2f}s, ~230M rows scanned)")
100+
print(f" ({time.perf_counter() - t0:.2f}s)")
101+
102+
print(
103+
"\nAverage 2m-temperature per (lat, lon) cell, globally, "
104+
"2020-01-01 00:00-05:00 UTC (°C):"
105+
)
106+
t0 = time.perf_counter()
107+
gridded = ctx.sql(
108+
"""
109+
SELECT latitude, longitude, AVG("2m_temperature") - 273.15 AS avg_c
110+
FROM era5.surface
111+
WHERE time BETWEEN TIMESTAMP '2020-01-01'
112+
AND TIMESTAMP '2020-01-01 05:00:00'
113+
GROUP BY latitude, longitude
114+
ORDER BY latitude DESC, longitude
115+
"""
116+
).to_dataset(dims=["latitude", "longitude"], template=ds)
117+
print(gridded)
118+
print(f" ({time.perf_counter() - t0:.2f}s)")
98119

99120

100121
if __name__ == "__main__":

0 commit comments

Comments
 (0)