Skip to content

Benchmarks

These benchmarks compare gometry with Shapely, pyproj, h3-py, Mercantile, and other Python libraries across geometry, coordinate transforms, grids, and spatial indexes.

API comparisons

Array construction & I/O

API / inputgometryComparator
from_wkb mixed EWKB 10k mixed EWKB gometry 1.47 ms 1.67× faster2.47 ms Shapely
from_arrow mixed GeoArrow WKB 100k mixed GeoArrow WKB / 10% missing gometry 11.47 ms 2.26× faster26.24 ms GeoPandas
to_wkb mixed EWKB 10k mixed EWKB gometry 732.39 us 4.35× faster3.19 ms Shapely
coords matrix and row_index 100k vertices / float64 matrix + int64 row index gometry 239.41 us 2.01× faster480.23 us Shapely
points from NumPy XY 10k NumPy XY gometry 5.50 us 203.25× faster1.13 ms Shapely
from WKT mixed geometries 10k realistic mixed WKT gometry 4.36 ms 3.28× faster14.32 ms Shapely
from GeoJSON countries 217 countries / 2.26 MB gometry 16.48 ms 1.59× faster26.35 ms Shapely

Geometry

API / inputgometryComparator
intersects irregular polygon points 12k interior, boundary, and exterior probes gometry 1.44 ms 1.92× faster2.74 ms Shapely
prepared polygon contains coordinate probes 100k probes / 1,316-coordinate holed polygon gometry 4.58 ms 1.91× faster8.56 ms Shapely
dwithin pairwise 10k pairs / 50% matches gometry 4.73 us 55.22× faster263.41 us Shapely
area projected buildings 10k projected buildings gometry 170.94 us 1.08× faster186.09 us Shapely
length roads 10k roads / 100k vertices gometry 137.33 us 1.51× faster203.93 us Shapely
simplify Douglas-Peucker 10k roads / 100k vertices gometry 772.93 us 5.35× faster4.13 ms Shapely
buffer projected points 10k projected points gometry 828.19 us 62.35× faster51.45 ms Shapely
intersection pairwise 1k irregular polygon pairs gometry 7.14 ms Inconclusive7.51 ms Shapely
intersects pairwise polygons 1k irregular polygon pairs gometry 620.77 us Inconclusive594.60 us Shapely
coverage_union_all parcels 10k edge-matched parcels gometry 5.30 ms Inconclusive6.12 ms Shapely
is_valid mixed polygons 10k mixed polygons / 20% invalid gometry 5.50 ms 1.78× faster9.90 ms Shapely
repair linework 1k invalid polygons gometry 12.72 ms 7.32× faster93.74 ms Shapely
bounds projected buildings 10k projected buildings gometry 147.84 us 1.21× faster180.83 us Shapely
Intersect short lines with a rectangle 10,000 three-vertex lines; 40% crossing, 40% inside, 20% outside gometry 13.15 ms 3.45× faster45.60 ms Shapely
point_on_surface buildings 10k concave and holed buildings gometry 1.01 ms 2.14× faster2.15 ms Shapely

CRS & geodesy

API / inputgometryComparator
to_crs masked points 200k points / 10% missing ‡gometry 7.11 ms 11.13× faster78.67 ms GeoPandas
crs_transform WGS84 to Web Mercator 10k EPSG:4326 to 3857 gometry 344.88 us 2.34× faster807.41 us pyproj
geodesic distance 10k WGS84 pairs †gometry 8.26 ms Inconclusive8.32 ms pyproj
geodesic destination 10k WGS84 destinations †gometry 3.53 ms 1.22× faster4.43 ms pyproj + Shapely + GeoPandas

Discrete global grids

API / inputgometryComparator
geohash encode tokens 10k WGS84 points / precision 6 gometry 605.88 us 6.84× faster4.20 ms pygeohash
h3 cover center Brazil Brazil res5 / 32,260 cells gometry 13.51 ms 2.35× faster32.13 ms h3-py
h3_compact 32,260 to 1,732 cells gometry 477.88 us Inconclusive487.70 us h3-py

Spatial index

API / inputgometryComparator
one-shot join within 10k POIs x 217 countries gometry 44.90 ms 1.41× slower31.63 ms Shapely
index join within 10k POIs x 217 countries gometry 14.75 ms 2.10× faster31.27 ms Shapely
index candidates 1k queries x 10k polygons gometry 1.46 ms 3.76× faster5.48 ms Shapely
index nearest k=1 1k non-intersecting queries x 10k polygons gometry 2.20 ms 2.42× faster5.34 ms Shapely
exact rectangle query: packed points 256 viewports / 10k projected points / varied hit counts gometry 1.38 ms 1.21× faster1.70 ms Shapely
exact rectangle query: mixed geometries 256 viewports / 10k projected points, lines, polygons, and holes gometry 6.96 ms 3.69× slower1.89 ms Shapely
exact rectangle query: geographic geometries 256 viewports / 10k mixed EPSG:4326 geometries away from seams and poles gometry 7.78 ms 4.30× slower1.83 ms Shapely
index build 10k polygons gometry 627.46 us 2.10× faster1.32 ms Shapely

† geodesic/ellipsoidal metric. ‡ gometry uses its admitted in-core projection path; this is not a claim about arbitrary CRS transforms.

Reference implementations

Ellipsoidal area and length along straight longitude/latitude edges are compared with a Python/NumPy quadrature reference.

API / inputgometryComparator
ellipsoidal chart-edge country area 217 countries gometry 166.90 ms 1.27× slower131.97 ms Python/NumPy quadrature reference
ellipsoidal chart-edge exterior length 1,034 exteriors / 16,135 vertices gometry 2.50 ms 68.55× faster171.40 ms Python/NumPy quadrature reference

Scaling

Call time as input or output size grows. Whiskers show the range across paired process blocks.

Union of edge-matched areas

Edge-matched service areas.

Union of edge-matched areas. Median call times — 64 geometries: gometry 690.81 us, Shapely 1.78 ms; 256 geometries: gometry 3.18 ms, Shapely 7.27 ms; 1024 geometries: gometry 13.85 ms, Shapely 28.34 ms.

Union of edge-matched areas. Median call times — 64 geometries: gometry 690.81 us, Shapely 1.78 ms; 256 geometries: gometry 3.18 ms, Shapely 7.27 ms; 1024 geometries: gometry 13.85 ms, Shapely 28.34 ms.

Union of disjoint polygons

Disjoint unit squares on a grid.

Union of disjoint polygons. Median call times — 1000 geometries: gometry 2.61 ms, Shapely 28.68 ms; 4000 geometries: gometry 11.75 ms, Shapely 146.94 ms; 16000 geometries: gometry 49.94 ms, Shapely 728.01 ms.

Union of disjoint polygons. Median call times — 1000 geometries: gometry 2.61 ms, Shapely 28.68 ms; 4000 geometries: gometry 11.75 ms, Shapely 146.94 ms; 16000 geometries: gometry 49.94 ms, Shapely 728.01 ms.

Intersection with many holes

Square shell with square holes, cut by a box.

Intersection with many holes. Median call times — 250 holes: gometry 541.12 us, Shapely 768.20 us; 1000 holes: gometry 2.43 ms, Shapely 3.01 ms; 4000 holes: gometry 9.79 ms, Shapely 12.65 ms.

Intersection with many holes. Median call times — 250 holes: gometry 541.12 us, Shapely 768.20 us; 1000 holes: gometry 2.43 ms, Shapely 3.01 ms; 4000 holes: gometry 9.79 ms, Shapely 12.65 ms.

Point-in-polygon queries

Repeated coordinate queries against a prepared polygon with three holes.

Point-in-polygon queries. Median call times — 1000 probes: gometry 32.56 us, Shapely 67.67 us; 10000 probes: gometry 773.04 us, Shapely 1.55 ms; 100000 probes: gometry 4.72 ms, Shapely 9.27 ms.

Point-in-polygon queries. Median call times — 1000 probes: gometry 32.56 us, Shapely 67.67 us; 10000 probes: gometry 773.04 us, Shapely 1.55 ms; 100000 probes: gometry 4.72 ms, Shapely 9.27 ms.

Tile cover by output size

Brazil bounding box.

Tile cover by output size. Median call times — 990 tiles: gometry 20.47 us, Mercantile 235.22 us; 3960 tiles: gometry 62.69 us, Mercantile 987.73 us; 15340 tiles: gometry 212.62 us, Mercantile 4.21 ms.

Tile cover by output size. Median call times — 990 tiles: gometry 20.47 us, Mercantile 235.22 us; 3960 tiles: gometry 62.69 us, Mercantile 987.73 us; 15340 tiles: gometry 212.62 us, Mercantile 4.21 ms.

Index queries as the index grows

1,000 queries against a growing polygon index.

Bounding-box candidates, without exact predicate refinement.

Index queries as the index grows. Median call times — 1000 polygons: gometry 86.53 us, Shapely 69.12 us; 5000 polygons: gometry 96.63 us, Shapely 97.45 us; 10000 polygons: gometry 97.49 us, Shapely 111.25 us.

Index queries as the index grows. Median call times — 1000 polygons: gometry 86.53 us, Shapely 69.12 us; 5000 polygons: gometry 96.63 us, Shapely 97.45 us; 10000 polygons: gometry 97.49 us, Shapely 111.25 us.

Index queries by hit rate

1,000 queries against 10,000 indexed polygons.

Bounding-box candidates, without exact predicate refinement.

Index queries by hit rate. Median call times — 0.01 fraction: gometry 23.93 us, Shapely 13.86 us; 0.1 fraction: gometry 29.51 us, Shapely 22.32 us; 0.5 fraction: gometry 58.55 us, Shapely 59.98 us.

Index queries by hit rate. Median call times — 0.01 fraction: gometry 23.93 us, Shapely 13.86 us; 0.1 fraction: gometry 29.51 us, Shapely 22.32 us; 0.5 fraction: gometry 58.55 us, Shapely 59.98 us.

Index queries returning more candidates

One query returning a growing number of candidates.

Bounding-box candidates, without exact predicate refinement.

Index queries returning more candidates. Median call times — 1 pairs/query: gometry 972.7 ns, Shapely 647.4 ns; 10 pairs/query: gometry 992.0 ns, Shapely 967.2 ns; 100 pairs/query: gometry 1.59 us, Shapely 1.82 us.

Index queries returning more candidates. Median call times — 1 pairs/query: gometry 972.7 ns, Shapely 647.4 ns; 10 pairs/query: gometry 992.0 ns, Shapely 967.2 ns; 100 pairs/query: gometry 1.59 us, Shapely 1.82 us.

Methodology

Each workload uses six to twelve paired measurements after warm-up, alternating which library runs first. Outputs are checked for equivalent rows, types, coordinates, and topology before timing.

Ratios summarize paired call times. Labels use confidence intervals with at least 95% coverage and a 3% practical-equivalence margin:

Label Meaning
Faster / slower The entire interval is beyond the 3% margin.
Similar The entire interval is within the margin.
Inconclusive The interval is too wide or crosses a decision boundary.

Measurements used one pinned CPU with the powersave governor and concurrent host activity.

Run environment

Measured on AMD Ryzen 9 5950X 16-Core Processor with Linux 7.2.9 and CPython 3.15.0. Benchmark harness commit: d801b232. Gometry producer source commit: d801b232 (bound to the loaded wheel by its receipt).

Versions: GeoPandas 1.2.0, h3-py 4.5.0, Mercantile 1.2.1, NumPy 2.5.4, pyarrow 26.0.0, pygeohash 3.5.1, pyproj 3.8.0, Shapely 2.2.0, GEOS 3.14.1, PROJ 9.8.1.

Raw measurements · Build provenance.