Skip to content

Avoid tiny numpy arrays in numba: optimize geometry.py - #1790

Draft
Sevans711 wants to merge 5 commits into
mainfrom
sevans/tinynumpynumba-optimize-geometry.py
Draft

Sevans711 wants to merge 5 commits into
mainfrom
sevans/tinynumpynumba-optimize-geometry.py

Conversation

@Sevans711

@Sevans711 Sevans711 commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #XXX

Overview

Optimizes numba routines in uxarray/grid/geometry.py to avoid constructing many tiny numpy arrays inside numba routines, as discussed in #1648.

This one was much more complicated to make progress on, compared to the other sub-issues already solved under 1648. The main reasons are: (1) its methods assign numpy arrays whose sizes depend on input variables' shapes, instead of being constant, so it's not trivial to convert to tuples; (2) there is less documentation and more "dead" code here that isn't doing anything, so it took some extra time to figure out what is going on; (3) there are more connections with methods defined in other parts of the code, such as arcs.py, bounds.py, bilinear.py, utils.py, either calling methods from here or being called by methods from here, and (4) call sites are often very deep (>5 clicks before getting to a top-level user-facing function) so it's trickier to track and understand the intended and actual use-cases for these functions sometimes.

Originally attempted more optimizations than this but had to backtrack when it make pytest suite fail in nontrivial ways that were difficult to debug.

Still very much a draft PR, mostly curious to see if these changes are enough to make any dent in ASV benchmarks, or if it might be better to focus more on some of those other files (arcs.py, bounds.py, etc) first. I suspect there might not be huge improvements just yet, because there are still quite a few tiny numpy arrays, and elsewhere I only really saw large speedups after finishing the cleanup to avoid all relevant numpy allocations.

PR Checklist

General

  • An issue is created and linked
  • Added appropriate labels (if your uxarray repo permissions allow it)
  • Filled out Overview and Expected Usage (if applicable) sections

Testing & Benchmarking

  • There is adequate test coverage of changes from this PR (add new tests if needed)
  • If this PR could affect performance, ran ASV benchmarks and confirmed they show expected behavior (add a new benchmark if necessary)

Documentation and Examples

  • Docstrings updated with any function changes, and included in all new functions
  • User (public) functions added to docs/api.rst; internal (private) function names start with an underscore (_)
  • If touched any notebook files, cleared the output of all cells before committing
  • If added new notebook files, put into appropriate directories and referenced in appropriate files

AI Disclosure

AI Usage: Claude for discussion and some code suggestions, plus GitHub Copilot's inline code suggestions

  • I have tested and take responsibility for all AI-generated content in my PR.

and _check_intersection. Improves docstring, refactors slightly (but behavior should be the same) and removes the unused lonlat computations.

Doesn't avoid allocating the `intersection_points` buffer because it's nontrivial to avoid that. (I separately tried it but my changes led to pytest suite failing and I'm not really sure why...) That buffer is only used for faces crossing the equator anyways, so it probably isn't worthwhile to worry too much about optimizing it...
now it avoids allocating tiny numpy arrays.

(Nontrivial to optimize the call site (`barycentric_coordinates_cartesian`) though because the call site might return length 3 or length 4 numpy arrays, depending on inputs. Might be simple to optimize if forcing inputs to barycentric_coordinates_cartesian to be tuples, though, maybe?)
@Sevans711 Sevans711 added scalability Related to scalability & performance efforts run-benchmark Run ASV benchmark workflow labels Sep 25, 2026
@github-actions

github-actions Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

ASV Benchmarking

Benchmark Comparison Results

Benchmarks that have improved:

Change Before [379c895] <v2026.09.1> After [74bf441] Ratio Benchmark (Parameter)
- 350M 316M 0.9 face_bounds.FaceBoundsColdStartRss.track_peakmem_open_and_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/mpas/QU/oQU480.231010.nc'))
- 350M 317M 0.9 face_bounds.FaceBoundsColdStartRss.track_peakmem_open_and_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/scrip/outCSne8/outCSne8.nc'))
- 350M 318M 0.91 face_bounds.FaceBoundsColdStartRss.track_peakmem_open_and_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/geoflow-small/grid.nc'))
- 350M 318M 0.91 face_bounds.FaceBoundsColdStartRss.track_peakmem_open_and_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/quad-hexagon/grid.nc'))
- 350M 275M 0.79 import.Imports.track_peakmem_import_uxarray
- 350M 312M 0.89 mpas_ocean.GradientColdStartRss.track_peakmem_gradient('480km')

Benchmarks that have stayed the same:

Change Before [379c895] <v2026.09.1> After [74bf441] Ratio Benchmark (Parameter)
5.26±0.2ms 4.90±0.2ms 0.93 bench_connectivity.Connectivity.time_edge_face('120km')
1.75±0.03ms 1.74±0.03ms 0.99 bench_connectivity.Connectivity.time_edge_face('480km')
4.70±0.7ms 4.15±0.2ms ~0.88 bench_connectivity.Connectivity.time_edge_node('120km')
1.33±0.01ms 1.35±0.02ms 1.01 bench_connectivity.Connectivity.time_edge_node('480km')
4.91±0.4ms 4.01±0.07ms ~0.82 bench_connectivity.Connectivity.time_face_edge('120km')
1.42±0.08ms 1.36±0.03ms 0.96 bench_connectivity.Connectivity.time_face_edge('480km')
5.85±0.4ms 5.65±0.03ms 0.97 bench_connectivity.Connectivity.time_face_face('120km')
2.05±0.02ms 2.06±0.01ms 1.01 bench_connectivity.Connectivity.time_face_face('480km')
43.9±0.7μs 44.6±0.9μs 1.02 bench_connectivity.Connectivity.time_face_node('120km')
44.7±1μs 44.2±1μs 0.99 bench_connectivity.Connectivity.time_face_node('480km')
406±20μs 397±5μs 0.98 bench_connectivity.Connectivity.time_n_nodes_per_face('120km')
319±10μs 316±10μs 0.99 bench_connectivity.Connectivity.time_n_nodes_per_face('480km')
6.05±1ms 5.52±0.1ms 0.91 bench_connectivity.Connectivity.time_node_edge('120km')
1.83±0.08ms 1.78±0.01ms 0.97 bench_connectivity.Connectivity.time_node_edge('480km')
84.5±7ms 84.4±5ms 1.00 bench_connectivity.Connectivity.time_node_face('120km')
4.72±0.05ms 4.80±0.2ms 1.02 bench_connectivity.Connectivity.time_node_face('480km')
7.76±0.1ms 7.57±1ms 0.97 face_bounds.FaceBounds.time_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/mpas/QU/oQU480.231010.nc'))
2.42±0.09ms 2.58±0.5ms 1.06 face_bounds.FaceBounds.time_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/scrip/outCSne8/outCSne8.nc'))
7.20±7s 8.34±10ms ~0.00 face_bounds.FaceBounds.time_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/geoflow-small/grid.nc'))
1.32±0.02ms 1.34±0.03ms 1.02 face_bounds.FaceBounds.time_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/quad-hexagon/grid.nc'))
57.3k 57.3k 1.00 face_bounds.FaceBounds.track_nbytes_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/mpas/QU/oQU480.231010.nc'))
12.3k 12.3k 1.00 face_bounds.FaceBounds.track_nbytes_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/scrip/outCSne8/outCSne8.nc'))
123k 123k 1.00 face_bounds.FaceBounds.track_nbytes_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/geoflow-small/grid.nc'))
128 128 1.00 face_bounds.FaceBounds.track_nbytes_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/quad-hexagon/grid.nc'))
1.27M 1.27M 1.00 face_bounds.FaceBounds.track_nbytes_grid_with_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/mpas/QU/oQU480.231010.nc'))
50.1k 50.1k 1.00 face_bounds.FaceBounds.track_nbytes_grid_with_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/scrip/outCSne8/outCSne8.nc'))
1.48M 1.48M 1.00 face_bounds.FaceBounds.track_nbytes_grid_with_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/geoflow-small/grid.nc'))
712 712 1.00 face_bounds.FaceBounds.track_nbytes_grid_with_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/quad-hexagon/grid.nc'))
1.98M 1.87M 0.94 face_bounds.FaceBounds.track_peakmem_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/mpas/QU/oQU480.231010.nc'))
1.97M 1.86M 0.94 face_bounds.FaceBounds.track_peakmem_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/scrip/outCSne8/outCSne8.nc'))
2.14M 2.02M 0.95 face_bounds.FaceBounds.track_peakmem_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/geoflow-small/grid.nc'))
35.5k 35.5k 1.00 face_bounds.FaceBounds.track_peakmem_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/quad-hexagon/grid.nc'))
1.10±0.02μs 1.10±0.01μs 1.00 geometry_kernels.AccucrossKernels.time_accucross
2.48±0.01μs 2.50±0.02μs 1.01 geometry_kernels.AccucrossKernels.time_accucross_pair
415±10ns 390±8ns 0.94 geometry_kernels.EFTPrimitives.time_acc_sqrt_re
415±30ns 390±9ns 0.94 geometry_kernels.EFTPrimitives.time_diff_of_products
391±20ns 346±20ns ~0.88 geometry_kernels.EFTPrimitives.time_two_prod
360±8ns 351±9ns 0.97 geometry_kernels.EFTPrimitives.time_two_sum
591±20ns 606±10ns 1.03 geometry_kernels.GCAConstLatIntersection.time_accux_constlat_kernel
676±20ns 671±5ns 0.99 geometry_kernels.GCAConstLatIntersection.time_gca_const_lat_intersection
696±30ns 686±20ns 0.99 geometry_kernels.GCAConstLatIntersection.time_try_gca_const_lat_intersection
721±10ns 716±10ns 0.99 geometry_kernels.GCAGCAIntersection.time_accux_gca_kernel
846±20ns 806±10ns 0.95 geometry_kernels.GCAGCAIntersection.time_gca_gca_intersection
912±20ns 936±20ns 1.03 geometry_kernels.GCAGCAIntersection.time_try_gca_gca_intersection
37.7±0.4μs 37.8±0.8μs 1.00 geometry_kernels.OrientPredicates.time_on_minor_arc
37.4±0.5μs 38.2±1μs 1.02 geometry_kernels.OrientPredicates.time_orient3d_on_sphere
3.09±0.02ms 3.08±0ms 1.00 geometry_samebody.SameBodyConstLat.time_accux_dispatch
1.32±0ms 1.32±0ms 1.00 geometry_samebody.SameBodyConstLat.time_accux_kernel
2.08±0.02ms 2.08±0.02ms 1.00 geometry_samebody.SameBodyConstLat.time_fp64_dispatch
151±0.2μs 153±0.2μs 1.01 geometry_samebody.SameBodyConstLat.time_fp64_kernel
28.5±0.7ms 28.2±0.2ms 0.99 geometry_samebody_gcagca.SameBodyGcaGca.time_accux_dispatch
6.79±0.01ms 6.81±0.03ms 1.00 geometry_samebody_gcagca.SameBodyGcaGca.time_accux_kernel
21.2±0.03ms 21.0±0.05ms 0.99 geometry_samebody_gcagca.SameBodyGcaGca.time_fp64_dispatch
867±2μs 866±2μs 1.00 geometry_samebody_gcagca.SameBodyGcaGca.time_fp64_kernel
916±5ms 915±10ms 1.00 import.Imports.timeraw_import_uxarray
2.06±0.05ms 2.07±0.03ms 1.00 mpas_ocean.CheckNorm.time_check_norm('120km')
1.56±0.01ms 1.57±0.01ms 1.01 mpas_ocean.CheckNorm.time_check_norm('480km')
1.02±0.02ms 1.03±0.01ms 1.01 mpas_ocean.ConnectivityConstruction.time_face_face_connectivity('120km')
496±8μs 506±7μs 1.02 mpas_ocean.ConnectivityConstruction.time_face_face_connectivity('480km')
611±3μs 619±8μs 1.01 mpas_ocean.ConnectivityConstruction.time_n_nodes_per_face('120km')
550±9μs 549±9μs 1.00 mpas_ocean.ConnectivityConstruction.time_n_nodes_per_face('480km')
4.97±0.02ms 4.95±0.06ms 1.00 mpas_ocean.ConstructFaceLatLon.time_cartesian_averaging('120km')
3.40±0.01ms 3.41±0.09ms 1.00 mpas_ocean.ConstructFaceLatLon.time_cartesian_averaging('480km')
100.0±0.6ms 99.0±0.2ms 0.99 mpas_ocean.ConstructFaceLatLon.time_welzl('120km')
10.4±0.2ms 9.80±0.3ms 0.94 mpas_ocean.ConstructFaceLatLon.time_welzl('480km')
21.0±0.03ms 20.8±0.02ms 0.99 mpas_ocean.ConstructTreeStructures.time_ball_tree('120km')
1.06±0.04ms 1.04±0.02ms 0.98 mpas_ocean.ConstructTreeStructures.time_ball_tree('480km')
10.6±0.02ms 10.5±0.08ms 0.99 mpas_ocean.ConstructTreeStructures.time_kd_tree('120km')
655±30μs 619±10μs 0.95 mpas_ocean.ConstructTreeStructures.time_kd_tree('480km')
577±10ms 557±5ms 0.97 mpas_ocean.CrossSections.time_const_lat('120km', 1)
286±3ms 286±7ms 1.00 mpas_ocean.CrossSections.time_const_lat('120km', 2)
145±4ms 147±0.9ms 1.01 mpas_ocean.CrossSections.time_const_lat('120km', 4)
494±20ms 491±9ms 0.99 mpas_ocean.CrossSections.time_const_lat('480km', 1)
251±10ms 248±3ms 0.99 mpas_ocean.CrossSections.time_const_lat('480km', 2)
127±3ms 126±2ms 0.99 mpas_ocean.CrossSections.time_const_lat('480km', 4)
350M 337M 0.96 mpas_ocean.CrossSectionsPeakMem.track_peakmem_const_lat('120km', 1)
350M 337M 0.96 mpas_ocean.CrossSectionsPeakMem.track_peakmem_const_lat('120km', 2)
350M 336M 0.96 mpas_ocean.CrossSectionsPeakMem.track_peakmem_const_lat('120km', 4)
350M 320M 0.91 mpas_ocean.CrossSectionsPeakMem.track_peakmem_const_lat('480km', 1)
350M 320M 0.91 mpas_ocean.CrossSectionsPeakMem.track_peakmem_const_lat('480km', 2)
350M 320M 0.91 mpas_ocean.CrossSectionsPeakMem.track_peakmem_const_lat('480km', 4)
24.0±0.1ms 24.4±0.6ms 1.02 mpas_ocean.DualMesh.time_dual_mesh_construction('120km')
2.69±0.1ms 2.93±0.2ms 1.09 mpas_ocean.DualMesh.time_dual_mesh_construction('480km')
15.2±0.7ms 15.5±2ms 1.02 mpas_ocean.FaceAreas.time_face_areas('120km')
3.81±0.2ms 3.95±0.2ms 1.04 mpas_ocean.FaceAreas.time_face_areas('480km')
229k 229k 1.00 mpas_ocean.FaceAreas.track_nbytes_face_areas('120km')
14.3k 14.3k 1.00 mpas_ocean.FaceAreas.track_nbytes_face_areas('480km')
2.12M 2.12M 1.00 mpas_ocean.FaceAreas.track_peakmem_face_areas('120km')
728k 730k 1.00 mpas_ocean.FaceAreas.track_peakmem_face_areas('480km')
844±6ms 854±10ms 1.01 mpas_ocean.GeoDataFrame.time_to_geodataframe('120km', False)
50.0±0.6ms 49.2±0.5ms 0.98 mpas_ocean.GeoDataFrame.time_to_geodataframe('120km', True)
72.6±0.1ms 74.2±0.2ms 1.02 mpas_ocean.GeoDataFrame.time_to_geodataframe('480km', False)
5.30±0.3ms 5.00±0.3ms 0.94 mpas_ocean.GeoDataFrame.time_to_geodataframe('480km', True)
13.8±0.6ms 14.1±0.5ms 1.02 mpas_ocean.Gradient.time_gradient('120km')
1.69±0ms 1.69±0.02ms 1.00 mpas_ocean.Gradient.time_gradient('480km')
457k 457k 1.00 mpas_ocean.Gradient.track_nbytes_gradient('120km')
28.7k 28.7k 1.00 mpas_ocean.Gradient.track_nbytes_gradient('480km')
3.2M 3.2M 1.00 mpas_ocean.Gradient.track_peakmem_gradient('120km')
204k 204k 1.00 mpas_ocean.Gradient.track_peakmem_gradient('480km')
350M 333M 0.95 mpas_ocean.GradientColdStartRss.track_peakmem_gradient('120km')
269±10μs 259±7μs 0.97 mpas_ocean.HoleEdgeIndices.time_construct_hole_edge_indices('120km')
127±7μs 129±2μs 1.01 mpas_ocean.HoleEdgeIndices.time_construct_hole_edge_indices('480km')
182±3μs 185±2μs 1.02 mpas_ocean.Integrate.time_integrate('120km')
162±0.9μs 166±2μs 1.03 mpas_ocean.Integrate.time_integrate('480km')
18.4M 18.4M 1.00 mpas_ocean.Integrate.track_nbytes_integrate('120km')
1.2M 1.2M 1.00 mpas_ocean.Integrate.track_nbytes_integrate('480km')
189±0.7ms 189±3ms 1.00 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('120km', 'exclude')
191±1ms 190±4ms 1.00 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('120km', 'include')
189±3ms 190±4ms 1.01 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('120km', 'split')
13.7±0.2ms 13.7±0.7ms 0.99 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('480km', 'exclude')
13.5±0.3ms 13.7±0.2ms 1.01 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('480km', 'include')
14.0±0.1ms 13.8±0.8ms 0.99 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('480km', 'split')
272±1ms 272±1ms 1.00 mpas_ocean.NeighborhoodBuild.time_build('120km', 1.0)
1.44±0.01s 1.43±0.01s 0.99 mpas_ocean.NeighborhoodBuild.time_build('120km', 15.0)
561±2ms 563±2ms 1.00 mpas_ocean.NeighborhoodBuild.time_build('120km', 5.0)
14.7±0.1ms 14.8±0.1ms 1.00 mpas_ocean.NeighborhoodBuild.time_build('480km', 1.0)
27.8±0.06ms 28.3±0.2ms 1.02 mpas_ocean.NeighborhoodBuild.time_build('480km', 15.0)
18.1±0.02ms 18.1±0.1ms 1.00 mpas_ocean.NeighborhoodBuild.time_build('480km', 5.0)
269±0.7ms 267±0.5ms 0.99 mpas_ocean.NeighborhoodBuild.time_query_radius('120km', 1.0)
1.42±0s 1.43±0.01s 1.01 mpas_ocean.NeighborhoodBuild.time_query_radius('120km', 15.0)
560±2ms 558±1ms 1.00 mpas_ocean.NeighborhoodBuild.time_query_radius('120km', 5.0)
14.4±0.02ms 14.2±0.07ms 0.99 mpas_ocean.NeighborhoodBuild.time_query_radius('480km', 1.0)
27.5±0.1ms 27.5±0.05ms 1.00 mpas_ocean.NeighborhoodBuild.time_query_radius('480km', 15.0)
17.9±0.1ms 17.7±0.1ms 0.99 mpas_ocean.NeighborhoodBuild.time_query_radius('480km', 5.0)
1.19 1.19 1.00 mpas_ocean.NeighborhoodBuild.track_mean_neighbors('120km', 1.0)
612.76 612.76 1.00 mpas_ocean.NeighborhoodBuild.track_mean_neighbors('120km', 15.0)
74.17 74.17 1.00 mpas_ocean.NeighborhoodBuild.track_mean_neighbors('120km', 5.0)
1.0 1.0 1.00 mpas_ocean.NeighborhoodBuild.track_mean_neighbors('480km', 1.0)
37.29 37.29 1.00 mpas_ocean.NeighborhoodBuild.track_mean_neighbors('480km', 15.0)
6.57 6.57 1.00 mpas_ocean.NeighborhoodBuild.track_mean_neighbors('480km', 5.0)
728k 728k 1.00 mpas_ocean.NeighborhoodBuild.track_nbytes_neighbors('120km', 1.0)
141M 141M 1.00 mpas_ocean.NeighborhoodBuild.track_nbytes_neighbors('120km', 15.0)
17.4M 17.4M 1.00 mpas_ocean.NeighborhoodBuild.track_nbytes_neighbors('120km', 5.0)
43k 43k 1.00 mpas_ocean.NeighborhoodBuild.track_nbytes_neighbors('480km', 1.0)
563k 563k 1.00 mpas_ocean.NeighborhoodBuild.track_nbytes_neighbors('480km', 15.0)
123k 123k 1.00 mpas_ocean.NeighborhoodBuild.track_nbytes_neighbors('480km', 5.0)
5.72M 5.72M 1.00 mpas_ocean.NeighborhoodBuild.track_peakmem_build('120km', 1.0)
145M 145M 1.00 mpas_ocean.NeighborhoodBuild.track_peakmem_build('120km', 15.0)
21.5M 21.5M 1.00 mpas_ocean.NeighborhoodBuild.track_peakmem_build('120km', 5.0)
362k 362k 1.00 mpas_ocean.NeighborhoodBuild.track_peakmem_build('480km', 1.0)
825k 825k 1.00 mpas_ocean.NeighborhoodBuild.track_peakmem_build('480km', 15.0)
384k 384k 1.00 mpas_ocean.NeighborhoodBuild.track_peakmem_build('480km', 5.0)
49.1±0.8ms 48.6±1ms 0.99 mpas_ocean.NeighborhoodDask.time_mean('120km', 'grid_chunks')
25.0±0.07ms 25.1±0.3ms 1.00 mpas_ocean.NeighborhoodDask.time_mean('120km', 'numpy')
44.8±0.7ms 44.3±0.7ms 0.99 mpas_ocean.NeighborhoodDask.time_mean('120km', 'time_chunks')
11.3±0.2ms 12.9±0.7ms ~1.14 mpas_ocean.NeighborhoodDask.time_mean('480km', 'grid_chunks')
606±20μs 614±10μs 1.01 mpas_ocean.NeighborhoodDask.time_mean('480km', 'numpy')
7.79±0.1ms 8.75±0.7ms ~1.12 mpas_ocean.NeighborhoodDask.time_mean('480km', 'time_chunks')
5.84M 5.84M 1.00 mpas_ocean.NeighborhoodDask.track_peakmem_mean('120km', 'grid_chunks')
2.75M 2.75M 1.00 mpas_ocean.NeighborhoodDask.track_peakmem_mean('120km', 'numpy')
5.69M 5.68M 1.00 mpas_ocean.NeighborhoodDask.track_peakmem_mean('120km', 'time_chunks')
685k 686k 1.00 mpas_ocean.NeighborhoodDask.track_peakmem_mean('480km', 'grid_chunks')
177k 177k 1.00 mpas_ocean.NeighborhoodDask.track_peakmem_mean('480km', 'numpy')
546k 542k 0.99 mpas_ocean.NeighborhoodDask.track_peakmem_mean('480km', 'time_chunks')
14.1±0.03s 14.1±0.1s 1.00 mpas_ocean.NeighborhoodReduce.time_dataset_reduce('120km', 'mean')
14.7±0.03s 14.8±0.07s 1.01 mpas_ocean.NeighborhoodReduce.time_dataset_reduce('120km', 'median')
248±2ms 250±1ms 1.01 mpas_ocean.NeighborhoodReduce.time_dataset_reduce('480km', 'mean')
255±0.9ms 254±0.1ms 1.00 mpas_ocean.NeighborhoodReduce.time_dataset_reduce('480km', 'median')
1.49±0s 1.48±0s 1.00 mpas_ocean.NeighborhoodReduce.time_neighborhood_reduce('120km', 'mean')
1.70±0.01s 1.69±0s 1.00 mpas_ocean.NeighborhoodReduce.time_neighborhood_reduce('120km', 'median')
28.7±0.3ms 28.7±0.04ms 1.00 mpas_ocean.NeighborhoodReduce.time_neighborhood_reduce('480km', 'mean')
30.2±0.08ms 30.1±0.3ms 1.00 mpas_ocean.NeighborhoodReduce.time_neighborhood_reduce('480km', 'median')
42.6±0.2ms 42.7±0.2ms 1.00 mpas_ocean.NeighborhoodReduce.time_reduce('120km', 'mean')
259±0.4ms 260±0.8ms 1.00 mpas_ocean.NeighborhoodReduce.time_reduce('120km', 'median')
584±60μs 535±30μs 0.92 mpas_ocean.NeighborhoodReduce.time_reduce('480km', 'mean')
1.97±0.05ms 2.00±0.06ms 1.02 mpas_ocean.NeighborhoodReduce.time_reduce('480km', 'median')
239k 239k 1.00 mpas_ocean.NeighborhoodReduce.track_peakmem_reduce('120km', 'mean')
245k 245k 1.00 mpas_ocean.NeighborhoodReduce.track_peakmem_reduce('120km', 'median')
19.4k 19.4k 1.00 mpas_ocean.NeighborhoodReduce.track_peakmem_reduce('480km', 'mean')
19.9k 19.9k 1.00 mpas_ocean.NeighborhoodReduce.track_peakmem_reduce('480km', 'median')
413±10μs 409±50μs 0.99 mpas_ocean.PointInPolygon.time_face_search_lonlat('120km')
378±10μs 368±10μs 0.97 mpas_ocean.PointInPolygon.time_face_search_lonlat('480km')
402±30μs 401±40μs 1.00 mpas_ocean.PointInPolygon.time_face_search_xyz('120km')
390±40μs 343±20μs ~0.88 mpas_ocean.PointInPolygon.time_face_search_xyz('480km')
124±1ms 119±0.7ms 0.96 mpas_ocean.RemapDownsample.time_bilinear_remapping
17.3±0.2ms 17.5±0.5ms 1.01 mpas_ocean.RemapDownsample.time_inverse_distance_weighted_remapping
15.7±0.2ms 16.3±1ms 1.04 mpas_ocean.RemapDownsample.time_nearest_neighbor_remapping
1.22±0.01s 1.16±0.01s 0.95 mpas_ocean.RemapUpsample.time_bilinear_remapping
27.1±0.7ms 26.6±0.6ms 0.98 mpas_ocean.RemapUpsample.time_inverse_distance_weighted_remapping
11.5±0.2ms 12.1±0.3ms 1.05 mpas_ocean.RemapUpsample.time_nearest_neighbor_remapping
8.12±0.1ms 8.14±0.1ms 1.00 mpas_ocean.ZonalAverage.time_zonal_average('120km')
4.90±0.1ms 4.72±0.2ms 0.96 mpas_ocean.ZonalAverage.time_zonal_average('480km')
350M 338M 0.97 mpas_ocean.ZonalAveragePeakMem.track_peakmem_zonal_average('120km')
350M 322M 0.92 mpas_ocean.ZonalAveragePeakMem.track_peakmem_zonal_average('480km')
1.0074454127067276 1.0201186213980848 1.01 nogil_scaling.GILScaling.track_gil_scaling
6.90±0.1ms 6.66±0.08ms 0.97 quad_hexagon.QuadHexagon.time_open_dataset
5.82±0.1ms 5.66±0.06ms 0.97 quad_hexagon.QuadHexagon.time_open_grid
408 408 1.00 quad_hexagon.QuadHexagon.track_nbytes_open_dataset
392 392 1.00 quad_hexagon.QuadHexagon.track_nbytes_open_grid
73.2k 73.6k 1.01 quad_hexagon.QuadHexagon.track_peakmem_open_dataset
72.4k 72.7k 1.01 quad_hexagon.QuadHexagon.track_peakmem_open_grid

@cmdupuis3

Copy link
Copy Markdown
Collaborator

Seems like this might be a sub-issue of #1789 2b?

@Sevans711

Copy link
Copy Markdown
Collaborator Author

Seems like this might be a sub-issue of #1789 2b?

Agreed, thank you for flagging this connection. I think #1789 2b is basically the same thing as implied by #1648 (though 1789 additionally does a good job of clearly pointing out many locations where this optimization could still help). My preference would be to continue tracking that via 1648 if that sounds reasonable?

This PR fixes some of the geometry.py topics pointed out in that table, but it isn't yet seeing any noticeable speedups, so my plan is to keep it as draft for now, revisit after some of the other topics there get fixed, and then make a corresponding sub-issue of 1648 once this is ready for review.

@cmdupuis3

cmdupuis3 commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Yeah, that's fine, I'll just add a note in #1789 to track the sub-issues over there. I think the work can happen in parallel to the other sections, so that's actually kind of nice.

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

Labels

run-benchmark Run ASV benchmark workflow scalability Related to scalability & performance efforts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants