Timezone Finding Performance Benchmark
~3.50µs per lookup, ~286k/s - TimezoneFinder.timezone_at() over uniformly random query points in memory, the workload closest to a real query mix.
Measured on Darwin arm64, Python 3.14.2, using the Numba JIT point-in-polygon path. Continuous integration tracks a different one - the C extension without Numba, what a plain pip install timezonefinder gives you - so these figures are not comparable to the trend chart. See Benchmarking Methodology.
System Status
Python Environment
Python Version: 3.14.2 (CPython)
NumPy Version: 2.3.5
Platform: Darwin arm64
Processor: arm
TimezoneFinder Configuration
C Implementation Available: False
Numba JIT Available: True
Performance Optimizations
✗ Using pure Python point-in-polygon implementation
✓ Numba JIT compilation enabled
Benchmark Input Provenance
Fixture Version: 2
Timezone Data Version: 2026c
Benchmark Configuration
Benchmark Source: pytest-benchmark
Batch Size: 2,500
Each benchmark times one pass over 2,500 fixed, committed query points (see benchmarks/conftest.py). Mean/Median/StdDev/Min/Max below are for the full 2,500-query batch; Time/Query and Throughput divide and scale that out to a per-query figure.
In-Memory Mode
TimezoneFinder.timezone_at()
Configuration |
Mean |
Median |
StdDev |
Min |
Max |
Rounds |
Time/Query |
Throughput |
|---|---|---|---|---|---|---|---|---|
ambiguous-shortcut points, in-memory |
24.6ms |
24.8ms |
702µs |
22.9ms |
25.6ms |
42 |
9.84µs |
102k/s |
on-land points, in-memory |
14.8ms |
15.0ms |
491µs |
13.6ms |
15.5ms |
68 |
5.93µs |
169k/s |
random points, in-memory |
8.74ms |
8.87ms |
408µs |
7.94ms |
9.39ms |
88 |
3.50µs |
286k/s |
unique-shortcut points, in-memory |
2.80ms |
2.69ms |
230µs |
2.62ms |
3.58ms |
330 |
1.12µs |
894k/s |
TimezoneFinder.timezone_at_land()
Configuration |
Mean |
Median |
StdDev |
Min |
Max |
Rounds |
Time/Query |
Throughput |
|---|---|---|---|---|---|---|---|---|
in-memory |
15.9ms |
16.1ms |
586µs |
14.7ms |
16.9ms |
60 |
6.37µs |
157k/s |
File-Based Mode
TimezoneFinder.timezone_at()
Configuration |
Mean |
Median |
StdDev |
Min |
Max |
Rounds |
Time/Query |
Throughput |
|---|---|---|---|---|---|---|---|---|
ambiguous-shortcut points, file-based |
37.0ms |
37.2ms |
522µs |
36.0ms |
37.9ms |
26 |
14.8µs |
67.5k/s |
on-land points, file-based |
20.4ms |
20.7ms |
651µs |
19.0ms |
21.6ms |
45 |
8.16µs |
123k/s |
random points, file-based |
11.7ms |
11.9ms |
487µs |
10.7ms |
12.4ms |
75 |
4.68µs |
214k/s |
unique-shortcut points, file-based |
2.74ms |
2.69ms |
166µs |
2.61ms |
3.59ms |
317 |
1.10µs |
911k/s |
TimezoneFinder.timezone_at_land()
Configuration |
Mean |
Median |
StdDev |
Min |
Max |
Rounds |
Time/Query |
Throughput |
|---|---|---|---|---|---|---|---|---|
file-based |
21.8ms |
21.9ms |
338µs |
20.9ms |
22.3ms |
43 |
8.73µs |
115k/s |
TimezoneFinderL (heuristic-only)
Note
TimezoneFinderL does not support in-memory mode; shortcuts are always loaded from disk.
TimezoneFinderL.timezone_at() (ambiguous-shortcut points)
Configuration |
Mean |
Median |
StdDev |
Min |
Max |
Rounds |
Time/Query |
Throughput |
|---|---|---|---|---|---|---|---|---|
3.31ms |
3.17ms |
328µs |
2.94ms |
4.41ms |
250 |
1.32µs |
756k/s |
Performance Summary
In-memory vs file-based (TimezoneFinder.timezone_at()):
Random points: in-memory is 34% faster (1.34x) than file-based (8.74ms vs 11.7ms)
On-land points: in-memory is 38% faster (1.38x) than file-based (14.8ms vs 20.4ms)
Unique-shortcut points: file-based and in-memory perform about the same (2.74ms vs 2.80ms, 2.0% difference)
Ambiguous-shortcut points: in-memory is 51% faster (1.51x) than file-based (24.6ms vs 37.0ms)
TimezoneFinder.timezone_at_land(): in-memory is 37% faster (1.37x) than file-based (15.9ms vs 21.8ms)
Ambiguous-shortcut points are 8.8x slower than unique-shortcut points (in-memory): a unique shortcut resolves directly from the H3 index, while an ambiguous one falls through to the full point-in-polygon check.
Overall: fastest is TimezoneFinder.timezone_at() - unique-shortcut points, file-based (2.74ms), slowest is TimezoneFinder.timezone_at() - ambiguous-shortcut points, file-based (37.0ms) - 1250% faster (13.5x)