Skip to content

Avoid tiny numpy arrays in numba: optimize area.py - #1701

Merged
erogluorhan merged 5 commits into
mainfrom
sevans/tinynumpynumba-optimize-area.py
Sep 2, 2026
Merged

Avoid tiny numpy arrays in numba: optimize area.py#1701
erogluorhan merged 5 commits into
mainfrom
sevans/tinynumpynumba-optimize-area.py

Conversation

@Sevans711

@Sevans711 Sevans711 commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Closes #1699 (sub-issue of #1648)

Overview

Optimizes numba routines in uxarray/grid/area.py to avoid constructing many tiny numpy arrays inside numba routines, as discussed in #1648. Locally I saw roughly 4x speedup in a few face areas computations; hopefully ASV benchmarks will show similar improvements.

Minor note: intentionally left quadrature_dg and dw as numpy arrays because those are only constructed once.

Small expansions of PR scope:

  • Now raises ValueError in face areas computations when using an invalid order, instead of silently returning zeros. Added corresponding regression test in test_areas.py.
  • Improves docstrings for helper functions in area.py, e.g. adds notes about shapes of dG and dW arrays.
  • Hoists if gaussian out of for p in range(n_weights) in _face_area_from_quadrature. This surely has negligible impact compared to the other changes, but maybe matters a tiny amount?

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

  • Adequate tests are created if there is new functionality
  • Tests are not too basic (such as simply calling a function and nothing else)
  • [N/A] Tests cover all major paths in your new functions
  • If this PR could affect performance, ran ASV benchmarks and confirmed they show expected behavior (add a new benchmark if necessary)

AI Disclosure

AI Usage: Claude discussions, GitHub Copilot's inline code suggestions.

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

@Sevans711 Sevans711 added scalability Related to scalability & performance efforts run-benchmark Run ASV benchmark workflow labels Aug 21, 2026
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

ASV Benchmarking

Benchmark Comparison Results

Benchmarks that have improved:

Change Before [5e8021d] After [83e93d6] Ratio Benchmark (Parameter)
- 44.4±1ms 7.77±0.2ms 0.18 mpas_ocean.FaceAreas.time_face_areas('120km')
- 836k 742k 0.89 mpas_ocean.FaceAreas.track_peakmem_face_areas('480km')
- 126±2ms 29.2±0.3ms 0.23 mpas_ocean.Gradient.time_gradient('120km')
- 8.63±0.4ms 2.47±0.02ms 0.29 mpas_ocean.Gradient.time_gradient('480km')

Benchmarks that have stayed the same:

Change Before [5e8021d] After [83e93d6] Ratio Benchmark (Parameter)
96.5±1ms 96.6±1ms 1.00 bench_connectivity.Connectivity.time_edge_face('120km')
5.89±0.03ms 6.10±0.04ms 1.04 bench_connectivity.Connectivity.time_edge_face('480km')
95.5±1ms 98.0±1ms 1.03 bench_connectivity.Connectivity.time_edge_node('120km')
5.57±0.05ms 5.83±0.2ms 1.05 bench_connectivity.Connectivity.time_edge_node('480km')
94.9±0.8ms 97.4±3ms 1.03 bench_connectivity.Connectivity.time_face_edge('120km')
5.60±0.06ms 5.73±0.1ms 1.02 bench_connectivity.Connectivity.time_face_edge('480km')
425±8ms 413±2ms 0.97 bench_connectivity.Connectivity.time_face_face('120km')
25.9±1ms 25.9±0.1ms 1.00 bench_connectivity.Connectivity.time_face_face('480km')
42.1±2μs 38.6±2μs 0.92 bench_connectivity.Connectivity.time_face_node('120km')
38.7±2μs 38.1±2μs 0.98 bench_connectivity.Connectivity.time_face_node('480km')
255±7μs 243±6μs 0.95 bench_connectivity.Connectivity.time_n_nodes_per_face('120km')
199±2μs 197±9μs 0.99 bench_connectivity.Connectivity.time_n_nodes_per_face('480km')
103±2ms 94.6±0.4ms 0.92 bench_connectivity.Connectivity.time_node_edge('120km')
5.95±0.2ms 5.56±0.05ms 0.93 bench_connectivity.Connectivity.time_node_edge('480km')
39.5±2ms 39.2±1ms 0.99 bench_connectivity.Connectivity.time_node_face('120km')
2.52±0.06ms 2.44±0.03ms 0.97 bench_connectivity.Connectivity.time_node_face('480km')
4.19±0.08ms 4.11±0.07ms 0.98 face_bounds.FaceBounds.time_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/mpas/QU/oQU480.231010.nc'))
1.40±0.01ms 1.41±0.06ms 1.01 face_bounds.FaceBounds.time_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/scrip/outCSne8/outCSne8.nc'))
6.24±6s 5.89±8ms ~0.00 face_bounds.FaceBounds.time_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/geoflow-small/grid.nc'))
1.12±0.03ms 1.18±0.04ms 1.05 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'))
2.02M 2.02M 1.00 face_bounds.FaceBounds.track_peakmem_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/mpas/QU/oQU480.231010.nc'))
2.03M 2.03M 1.00 face_bounds.FaceBounds.track_peakmem_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/scrip/outCSne8/outCSne8.nc'))
2.19M 2.19M 1.00 face_bounds.FaceBounds.track_peakmem_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/geoflow-small/grid.nc'))
38.3k 38.3k 1.00 face_bounds.FaceBounds.track_peakmem_face_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/quad-hexagon/grid.nc'))
337M 337M 1.00 face_bounds.FaceBoundsColdStartRss.peakmem_open_and_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/mpas/QU/oQU480.231010.nc'))
369M 368M 1.00 face_bounds.FaceBoundsColdStartRss.peakmem_open_and_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/scrip/outCSne8/outCSne8.nc'))
339M 339M 1.00 face_bounds.FaceBoundsColdStartRss.peakmem_open_and_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/geoflow-small/grid.nc'))
338M 338M 1.00 face_bounds.FaceBoundsColdStartRss.peakmem_open_and_bounds(PosixPath('/home/runner/work/uxarray/uxarray/test/meshfiles/ugrid/quad-hexagon/grid.nc'))
621±50ns 606±10ns 0.98 geometry_kernels.AccucrossKernels.time_accucross
1.40±0.07μs 1.37±0.02μs 0.98 geometry_kernels.AccucrossKernels.time_accucross_pair
250±5ns 245±5ns 0.98 geometry_kernels.EFTPrimitives.time_acc_sqrt_re
241±5ns 230±4ns 0.95 geometry_kernels.EFTPrimitives.time_diff_of_products
210±4ns 211±5ns 1.00 geometry_kernels.EFTPrimitives.time_two_prod
210±5ns 206±10ns 0.98 geometry_kernels.EFTPrimitives.time_two_sum
786±30ns 766±9ns 0.97 geometry_kernels.GCAConstLatIntersection.time_accux_constlat_kernel
561±9ns 586±10ns 1.04 geometry_kernels.GCAConstLatIntersection.time_gca_const_lat_intersection
957±9ns 997±30ns 1.04 geometry_kernels.GCAConstLatIntersection.time_try_gca_const_lat_intersection
1.77±0.03μs 1.71±0.03μs 0.97 geometry_kernels.GCAGCAIntersection.time_accux_gca_kernel
671±20ns 656±20ns 0.98 geometry_kernels.GCAGCAIntersection.time_gca_gca_intersection
1.80±0.03μs 1.80±0.02μs 1.00 geometry_kernels.GCAGCAIntersection.time_try_gca_gca_intersection
22.9±0.1μs 23.1±0.9μs 1.01 geometry_kernels.OrientPredicates.time_on_minor_arc
421±9ns 406±20ns 0.96 geometry_kernels.OrientPredicates.time_orient3d_on_sphere
1.56±0.06ms 1.50±0.03ms 0.97 geometry_samebody.SameBodyConstLat.time_accux_dispatch
654±7μs 675±9μs 1.03 geometry_samebody.SameBodyConstLat.time_accux_kernel
1.05±0.01ms 1.06±0.02ms 1.01 geometry_samebody.SameBodyConstLat.time_fp64_dispatch
84.2±0.6μs 86.3±3μs 1.03 geometry_samebody.SameBodyConstLat.time_fp64_kernel
failed failed n/a geometry_samebody_gcagca.SameBodyGcaGca.time_accux_dispatch
failed failed n/a geometry_samebody_gcagca.SameBodyGcaGca.time_accux_kernel
failed failed n/a geometry_samebody_gcagca.SameBodyGcaGca.time_fp64_dispatch
failed failed n/a geometry_samebody_gcagca.SameBodyGcaGca.time_fp64_kernel
493±20ms 503±10ms 1.02 import.Imports.timeraw_import_uxarray
293M 293M 1.00 import.Imports.track_peakmem_import_uxarray
1.30±0.01ms 1.35±0.02ms 1.04 mpas_ocean.CheckNorm.time_check_norm('120km')
1.11±0.05ms 1.07±0.01ms 0.97 mpas_ocean.CheckNorm.time_check_norm('480km')
381±6ms 377±4ms 0.99 mpas_ocean.ConnectivityConstruction.time_face_face_connectivity('120km')
23.1±0.2ms 23.5±0.5ms 1.02 mpas_ocean.ConnectivityConstruction.time_face_face_connectivity('480km')
385±10μs 365±4μs 0.95 mpas_ocean.ConnectivityConstruction.time_n_nodes_per_face('120km')
324±10μs 307±8μs 0.95 mpas_ocean.ConnectivityConstruction.time_n_nodes_per_face('480km')
2.49±0.02ms 2.54±0.05ms 1.02 mpas_ocean.ConstructFaceLatLon.time_cartesian_averaging('120km')
2.06±0.05ms 1.96±0.05ms 0.95 mpas_ocean.ConstructFaceLatLon.time_cartesian_averaging('480km')
68.2±2ms 67.6±2ms 0.99 mpas_ocean.ConstructFaceLatLon.time_welzl('120km')
6.24±0.02ms 6.10±0.1ms 0.98 mpas_ocean.ConstructFaceLatLon.time_welzl('480km')
12.5±0.01ms 12.6±0.3ms 1.00 mpas_ocean.ConstructTreeStructures.time_ball_tree('120km')
750±10μs 771±8μs 1.03 mpas_ocean.ConstructTreeStructures.time_ball_tree('480km')
6.49±0.08ms 6.48±0.1ms 1.00 mpas_ocean.ConstructTreeStructures.time_kd_tree('120km')
452±30μs 476±7μs 1.05 mpas_ocean.ConstructTreeStructures.time_kd_tree('480km')
296±7ms 298±4ms 1.01 mpas_ocean.CrossSections.time_const_lat('120km', 1)
153±4ms 152±1ms 0.99 mpas_ocean.CrossSections.time_const_lat('120km', 2)
78.9±0.8ms 78.8±1ms 1.00 mpas_ocean.CrossSections.time_const_lat('120km', 4)
260±2ms 258±1ms 0.99 mpas_ocean.CrossSections.time_const_lat('480km', 1)
129±1ms 130±2ms 1.00 mpas_ocean.CrossSections.time_const_lat('480km', 2)
67.5±1ms 67.6±0.5ms 1.00 mpas_ocean.CrossSections.time_const_lat('480km', 4)
357M 359M 1.01 mpas_ocean.CrossSectionsPeakMem.peakmem_const_lat('120km', 1)
357M 357M 1.00 mpas_ocean.CrossSectionsPeakMem.peakmem_const_lat('120km', 2)
357M 357M 1.00 mpas_ocean.CrossSectionsPeakMem.peakmem_const_lat('120km', 4)
340M 340M 1.00 mpas_ocean.CrossSectionsPeakMem.peakmem_const_lat('480km', 1)
340M 340M 1.00 mpas_ocean.CrossSectionsPeakMem.peakmem_const_lat('480km', 2)
340M 340M 1.00 mpas_ocean.CrossSectionsPeakMem.peakmem_const_lat('480km', 4)
14.4±0.05ms 14.7±0.2ms 1.02 mpas_ocean.DualMesh.time_dual_mesh_construction('120km')
1.61±0.02ms 1.60±0.02ms 0.99 mpas_ocean.DualMesh.time_dual_mesh_construction('480km')
4.39±0.03ms 2.14±0.05ms ~0.49 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')
458±9ms 451±2ms 0.98 mpas_ocean.GeoDataFrame.time_to_geodataframe('120km', False)
27.8±0.4ms 26.9±0.8ms 0.97 mpas_ocean.GeoDataFrame.time_to_geodataframe('120km', True)
39.2±1ms 39.5±0.7ms 1.01 mpas_ocean.GeoDataFrame.time_to_geodataframe('480km', False)
457k 457k 1.00 mpas_ocean.Gradient.track_nbytes_gradient('120km')
28.7k 28.7k 1.00 mpas_ocean.Gradient.track_nbytes_gradient('480km')
5.08M 5.08M 1.00 mpas_ocean.Gradient.track_peakmem_gradient('120km')
328k 328k 1.00 mpas_ocean.Gradient.track_peakmem_gradient('480km')
355M 352M 0.99 mpas_ocean.GradientColdStartRss.peakmem_gradient('120km')
334M 332M 1.00 mpas_ocean.GradientColdStartRss.peakmem_gradient('480km')
258±4μs 256±10μs 0.99 mpas_ocean.HoleEdgeIndices.time_construct_hole_edge_indices('120km')
386±5μs 398±10μs 1.03 mpas_ocean.Integrate.time_integrate('120km')
320±10μs 296±6μs 0.92 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')
96.9±1ms 103±3ms 1.06 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('120km', 'exclude')
96.6±0.8ms 97.4±0.7ms 1.01 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('120km', 'include')
97.6±3ms 101±4ms 1.04 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('120km', 'split')
7.32±0.1ms 7.83±0.3ms 1.07 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('480km', 'exclude')
7.37±0.1ms 7.74±0.4ms 1.05 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('480km', 'split')
163±3ms 160±3ms 0.98 mpas_ocean.NeighborhoodBuild.time_build('120km', 1.0)
895±20ms 876±30ms 0.98 mpas_ocean.NeighborhoodBuild.time_build('120km', 15.0)
356±8ms 344±7ms 0.96 mpas_ocean.NeighborhoodBuild.time_build('120km', 5.0)
8.59±0.3ms 8.66±0.05ms 1.01 mpas_ocean.NeighborhoodBuild.time_build('480km', 1.0)
16.7±0.07ms 17.2±0.3ms 1.03 mpas_ocean.NeighborhoodBuild.time_build('480km', 15.0)
10.7±0.03ms 10.7±0.03ms 1.00 mpas_ocean.NeighborhoodBuild.time_build('480km', 5.0)
164±7ms 171±5ms 1.05 mpas_ocean.NeighborhoodBuild.time_query_radius('120km', 1.0)
853±3ms 858±10ms 1.01 mpas_ocean.NeighborhoodBuild.time_query_radius('120km', 15.0)
333±4ms 337±8ms 1.01 mpas_ocean.NeighborhoodBuild.time_query_radius('120km', 5.0)
8.50±0.08ms 8.48±0.04ms 1.00 mpas_ocean.NeighborhoodBuild.time_query_radius('480km', 1.0)
17.5±0.3ms 17.8±0.7ms 1.01 mpas_ocean.NeighborhoodBuild.time_query_radius('480km', 15.0)
11.3±0.3ms 11.0±0.03ms 0.97 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 824k 1.00 mpas_ocean.NeighborhoodBuild.track_peakmem_build('480km', 15.0)
384k 384k 1.00 mpas_ocean.NeighborhoodBuild.track_peakmem_build('480km', 5.0)
28.0±0.8ms 27.6±0.7ms 0.99 mpas_ocean.NeighborhoodDask.time_mean('120km', 'grid_chunks')
13.0±0.2ms 13.0±0.5ms 1.00 mpas_ocean.NeighborhoodDask.time_mean('120km', 'numpy')
25.8±1ms 26.1±0.7ms 1.01 mpas_ocean.NeighborhoodDask.time_mean('120km', 'time_chunks')
6.21±0.1ms 6.79±0.2ms 1.09 mpas_ocean.NeighborhoodDask.time_mean('480km', 'grid_chunks')
336±10μs 336±10μs 1.00 mpas_ocean.NeighborhoodDask.time_mean('480km', 'numpy')
4.62±0.07ms 4.81±0.1ms 1.04 mpas_ocean.NeighborhoodDask.time_mean('480km', 'time_chunks')
5.83M 5.83M 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.68M 5.67M 1.00 mpas_ocean.NeighborhoodDask.track_peakmem_mean('120km', 'time_chunks')
702k 754k 1.07 mpas_ocean.NeighborhoodDask.track_peakmem_mean('480km', 'grid_chunks')
177k 177k 1.00 mpas_ocean.NeighborhoodDask.track_peakmem_mean('480km', 'numpy')
538k 529k 0.98 mpas_ocean.NeighborhoodDask.track_peakmem_mean('480km', 'time_chunks')
8.28±0.03s 8.35±0.07s 1.01 mpas_ocean.NeighborhoodReduce.time_dataset_reduce('120km', 'mean')
8.73±0.02s 8.74±0.01s 1.00 mpas_ocean.NeighborhoodReduce.time_dataset_reduce('120km', 'median')
157±7ms 154±3ms 0.98 mpas_ocean.NeighborhoodReduce.time_dataset_reduce('480km', 'mean')
155±0.5ms 156±0.9ms 1.01 mpas_ocean.NeighborhoodReduce.time_dataset_reduce('480km', 'median')
894±10ms 894±20ms 1.00 mpas_ocean.NeighborhoodReduce.time_neighborhood_reduce('120km', 'mean')
1.03±0.01s 1.03±0.01s 1.00 mpas_ocean.NeighborhoodReduce.time_neighborhood_reduce('120km', 'median')
17.0±0.1ms 17.1±0.2ms 1.01 mpas_ocean.NeighborhoodReduce.time_neighborhood_reduce('480km', 'mean')
18.1±0.3ms 18.4±0.4ms 1.02 mpas_ocean.NeighborhoodReduce.time_neighborhood_reduce('480km', 'median')
21.3±0.1ms 22.0±0.7ms 1.03 mpas_ocean.NeighborhoodReduce.time_reduce('120km', 'mean')
166±7ms 161±7ms 0.97 mpas_ocean.NeighborhoodReduce.time_reduce('120km', 'median')
323±6μs 326±20μs 1.01 mpas_ocean.NeighborhoodReduce.time_reduce('480km', 'mean')
1.45±0.04ms 1.38±0.01ms 0.95 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')
231±5μs 233±30μs 1.01 mpas_ocean.PointInPolygon.time_face_search_lonlat('120km')
193±4μs 212±6μs 1.10 mpas_ocean.PointInPolygon.time_face_search_lonlat('480km')
228±9μs 234±20μs 1.03 mpas_ocean.PointInPolygon.time_face_search_xyz('120km')
177±4μs 193±10μs 1.09 mpas_ocean.PointInPolygon.time_face_search_xyz('480km')
117±0.3ms 113±0.8ms 0.96 mpas_ocean.RemapDownsample.time_bilinear_remapping
117±3ms 117±2ms 1.00 mpas_ocean.RemapDownsample.time_inverse_distance_weighted_remapping
9.19±0.03ms 9.38±0.2ms 1.02 mpas_ocean.RemapDownsample.time_nearest_neighbor_remapping
586±8ms 581±5ms 0.99 mpas_ocean.RemapUpsample.time_bilinear_remapping
22.1±1ms 20.7±0.2ms 0.94 mpas_ocean.RemapUpsample.time_inverse_distance_weighted_remapping
6.98±0.2ms 7.10±0.3ms 1.02 mpas_ocean.RemapUpsample.time_nearest_neighbor_remapping
5.39±0.4ms 5.35±0.5ms 0.99 mpas_ocean.ZonalAverage.time_zonal_average('120km')
2.93±0.1ms 2.68±0.07ms 0.91 mpas_ocean.ZonalAverage.time_zonal_average('480km')
359M 359M 1.00 mpas_ocean.ZonalAveragePeakMem.peakmem_zonal_average('120km')
342M 342M 1.00 mpas_ocean.ZonalAveragePeakMem.peakmem_zonal_average('480km')
3.56±0.1ms 3.65±0.09ms 1.03 quad_hexagon.QuadHexagon.time_open_dataset
3.15±0.1ms 3.01±0.1ms 0.96 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.5k 73.5k 1.00 quad_hexagon.QuadHexagon.track_peakmem_open_dataset
72.7k 72.8k 1.00 quad_hexagon.QuadHexagon.track_peakmem_open_grid

Benchmarks that have got worse:

Change Before [5e8021d] After [83e93d6] Ratio Benchmark (Parameter)
+ 3.05±0.1ms 3.48±0.05ms 1.14 mpas_ocean.GeoDataFrame.time_to_geodataframe('480km', True)
+ 113±6μs 129±4μs 1.14 mpas_ocean.HoleEdgeIndices.time_construct_hole_edge_indices('480km')
+ 7.29±0.1ms 8.20±0.3ms 1.12 mpas_ocean.MatplotlibConversion.time_dataarray_to_polycollection('480km', 'include')

@Sevans711 Sevans711 self-assigned this Aug 24, 2026

@cmdupuis3 cmdupuis3 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good, no issues in testing or benchmarking, and the approach here is fine.

@dylannelson dylannelson left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Was able to create the environment, run the the tests, observe the speed increases, and ran across no problems. Looks good, thank you!

@erogluorhan
erogluorhan merged commit f47b194 into main Sep 2, 2026
13 checks passed
@Sevans711
Sevans711 deleted the sevans/tinynumpynumba-optimize-area.py branch September 2, 2026 17:05
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.

Avoid tiny numpy arrays in numba: optimize area.py

4 participants