Benchmarks

How does PyGeoHash compare to the other geohash libraries on PyPI? This page publishes the numbers rather than leaving the question open. It is generated by scripts/run_comparison_benchmark.py from the suite in tests/test_benchmark_comparison.py, which measures every library on identical work.

What is measured

Every library receives the same inputs: latitude 42.6, longitude -5.6 and precision 9 for encoding, and the geohash ezs42e44y for decoding and bounding-box lookups. The encode cases assert that each library returns the same standard geohash, so the comparison is genuinely like for like.

Two libraries offer no bounding-box helper (pygeohash-fast and geohash-tools), so they appear only in the encode and decode tables. Two others are excluded from the suite entirely: geohash-hilbert computes a Hilbert-curve variant rather than a standard geohash, and mzgeohash takes no precision parameter, so equal work cannot be guaranteed.

The whole suite was run 7 times. Each library’s headline figure is the median of its per-run medians, and the range column gives the lowest and highest median it produced, so the run-to-run movement behind every number is visible. Ops/sec is derived from the headline median, and the final column is each library’s median divided by pygeohash’s.

Encode

Encode (42.6, -5.6) to a precision-9 geohash.

Library

Implementation

Median (ns)

Range over 7 runs (ns)

Ops/sec

vs pygeohash

geohashr

Rust extension

86

84 - 125

11,688,548

0.42x

pygeohash-fast

Rust extension

125

125 - 125

7,999,939

0.61x

pygeohash

C extension

204

202 - 206

4,898,352

1.00x

python-geohash

C++ extension

208

165 - 208

4,807,575

1.02x

libgeohash

pure Python

2,750

2,709 - 2,750

363,637

13.47x

geohash-tools

pure Python

3,833

3,792 - 3,834

260,892

18.78x

geolib

pure Python

10,584

10,542 - 10,834

94,482

51.84x

On this machine pygeohash is 1.02x faster than python-geohash and is 13.5x faster than libgeohash, the quickest pure-Python entry. geohashr, pygeohash-fast are faster still.

The repeated runs did not separate geohashr and pygeohash-fast; pygeohash and python-geohash. Their ranges of medians overlap, so their relative order in the table is within measurement noise and swaps between runs: read them as tied.

Decode

Decode ezs42e44y back to coordinates.

Library

Implementation

Median (ns)

Range over 7 runs (ns)

Ops/sec

vs pygeohash

geohashr

Rust extension

81

81 - 81

12,339,577

0.32x

pygeohash-fast

Rust extension

167

167 - 167

5,988,104

0.67x

pygeohash

C extension

250

250 - 542

3,999,970

1.00x

python-geohash

C++ extension

250

250 - 250

3,999,970

1.00x

libgeohash

pure Python

2,625

2,625 - 2,666

380,954

10.50x

geohash-tools

pure Python

3,375

3,375 - 3,417

296,297

13.50x

geolib

pure Python

57,708

57,458 - 62,541

17,329

230.83x

On this machine pygeohash is 1.00x faster than python-geohash and is 10.5x faster than libgeohash, the quickest pure-Python entry. geohashr, pygeohash-fast are faster still.

The repeated runs did not separate pygeohash and python-geohash. Their ranges of medians overlap, so their relative order in the table is within measurement noise and swaps between runs: read them as tied.

Bounding box

Look up the bounding box of the ezs42e44y cell.

Library

Implementation

Median (ns)

Range over 7 runs (ns)

Ops/sec

vs pygeohash

geohashr

Rust extension

104

104 - 105

9,580,832

0.16x

python-geohash

C++ extension

250

250 - 291

3,999,970

0.37x

pygeohash

C extension

667

666 - 667

1,499,312

1.00x

libgeohash

pure Python

2,750

2,750 - 2,792

363,634

4.12x

geolib

pure Python

43,875

43,041 - 44,208

22,792

65.78x

On this machine pygeohash takes 2.67x the median time of python-geohash and is 4.1x faster than libgeohash, the quickest pure-Python entry. geohashr is faster still.

Environment

These figures come from repeated runs on one machine. They are not an average across hardware, and they should be read as an ordering rather than as absolute throughput you can expect elsewhere.

  • Date of run: 2026-08-31 (7 repeats of the suite)

  • Machine: Apple M4 (arm64, 10 cores)

  • Operating system: Darwin 25.2.0

  • Python: CPython 3.12.11

  • pytest-benchmark: 5.3.0

Installed versions of every library measured:

  • geohash-tools 0.2.0

  • geohashr 1.6.0

  • geolib 1.0.7

  • libgeohash 0.1.1

  • pygeohash 3.3.2

  • pygeohash-fast 0.3.0

  • python-geohash 0.9.2

Reproducing this page

From a checkout, with the dev and benchmark extras installed:

uv pip install -e ".[dev,benchmark]"
python scripts/run_comparison_benchmark.py

The script runs the suite several times, reads the pytest-benchmark JSON reports, and rewrites this page with the numbers and the environment it observed. Rerun it on your own machine before quoting any of these figures as your own.

Caveats

  • Every figure is a median from one machine; a benchmark is a draw from a noisy process, not a constant.

  • The fastest entries take well under a microsecond, which is only tens of ticks of the platform timer, so their medians are coarsely quantized. Where two adjacent entries were not separated by the measurement, the note under the table says so and they should be read as tied.

  • Only the three operations above are measured. A library that is slower here may be faster on work this suite does not cover.

  • Install cost is not measured. pygeohash ships pre-built wheels and needs no compiler at install time, which is what motivated the comparison in the first place, but that is a packaging property rather than a speed result.