Skip to content

Benchmarks

There are two separate benchmark setups with different purposes:

Continuous benchmark — source and results at https://github.com/ringsaturn/tz-benchmark, visualized at https://ringsaturn.github.io/tz-benchmark/. Runs automatically in GitHub Actions on each release for cross-package comparison. Because GitHub Actions runners have different hardware than a developer machine, the absolute numbers differ from local runs, but the relative trends between packages are what matters here.

Local benchmark — the tables below were measured on an Apple MacBook Pro with Apple M3 Max. These give a more representative picture of real-world latency on modern hardware.

Methodology

Each finder is initialized once and reused for all queries, matching the recommended production pattern. Queries use a representative sample of global city coordinates plus intentional edge-case border points.

Go (tzf v1.2.0)

TargetDatasetScenarioMedian (ns)p99 (ns)Approx throughput (ops/s)Memory (MiB)
DefaultFindertopology-simplified + preindexedge case · GetTimezoneName500.01250.01694.9K74.90
FuzzyFinderpreindexedge case · GetTimezoneName250.0375.03521.1K2.40
Findertopology-simplifiededge case · GetTimezoneName250.0875.03022.1K72.70
FullFinderfull-precision + preindexedge case · GetTimezoneName542.01375.01586.3K422.90
Finderfull-precisionedge case · GetTimezoneName292.01167.02678.1K420.70
DefaultFindertopology-simplified + preindexrandom world cities · GetTimezoneName167.0791.03855.1K74.90
FuzzyFinderpreindexrandom world cities · GetTimezoneName167.0333.04608.3K2.40
Findertopology-simplifiedrandom world cities · GetTimezoneName209.01250.03076.0K72.70
FullFinderfull-precision + preindexrandom world cities · GetTimezoneName208.0917.03527.3K422.90
Finderfull-precisionrandom world cities · GetTimezoneName250.01167.02953.3K420.70
Findertopology-simplified + GridIndexrandom world cities · GetTimezoneName209.01167.03202.0K72.70
Findertopology-simplified (no GridIndex)random world cities · GetTimezoneName1833.02875.0612.4K67.00
DefaultFindertopology-simplified + preindexrandom world cities · GetTimezoneNames416.01375.01956.9K74.90
FuzzyFinderpreindexrandom world cities · GetTimezoneNames208.0334.04347.8K2.40
Findertopology-simplifiedrandom world cities · GetTimezoneNames417.01375.01931.2K72.70
FullFinderfull-precision + preindexrandom world cities · GetTimezoneNames459.01750.01623.1K422.90

Rust (tzf-rs v1.2.0 / v1.3.0)

Topology-Simplified (bundled) / Random Cities:

TargetDatasetScenarioMedian estimate (µs)Approx throughput (ops/s)Avg peak RSS (MiB)
Findertopology-simplifiedYStripes only0.64571,548,635112.30
Findertopology-simplifiedNo index4.3948227,54259.92
DefaultFindertopology-simplified + preindexYStripes only0.38002,631,787134.48
DefaultFindertopology-simplified + preindexNo index4.4922222,60885.66

Topology-Simplified (bundled) / Edge Cities (FuzzyFinder misses)

TargetDatasetScenarioMedian estimate (µs)Approx throughput (ops/s)
FuzzyFinderpreindexFuzzyFinder miss0.22004,546,074
DefaultFinder (YStripes)topology-simplified + preindexDefaultFinder (YStripes) fallback0.74561,341,184
Findertopology-simplifiedYStripes0.49752,010,131
Findertopology-simplifiedNo index4.3948227,542
DefaultFindertopology-simplified + preindexYStripes0.71541,397,858
DefaultFindertopology-simplified + preindexNo index4.4922222,608

Full-Precision (full):

TargetDatasetScenarioMedian estimate (µs)Approx throughput (ops/s)Avg peak RSS (MiB)
Finder (full)full-precisionYStripes only1.7158582,819568.78
Finder (full)full-precisionNo index38.937025,683260.95
DefaultFinder (full)full-precision + preindexYStripes only0.49842,006,421592.25
DefaultFinder (full)full-precision + preindexNo index6.6012151,488287.32

Python (tzfpy v1.2.0)

tzfpy is a PyO3 binding over tzf-rs. The benchmark uses pytest-benchmark and measures a single get_tz() call (random coordinate, topology-simplified dataset). Results from Apple MacBook Pro with Apple M3 Max.

Index modeMedian (µs)Mean (µs)Throughput (Kops/s)Memory
Default (YStripes enabled)1.79341.8321545.8~120 MB
No YStripes (_TZFPY_DISABLE_Y_STRIPES=1)2.52132.5338394.7Not measured

Per-call overhead is comparable to the raw Rust figures; the difference from tzf-rs numbers reflects the Python → Rust FFI cost via PyO3.

Key observations

  • YStripes index brings a dramatic improvement for full-precision Finder: from 37.7 µs (no index) to 2.1 µs — an ~18× speedup. The effect is smaller but still significant for the topology-simplified dataset (6.5 µs → 1.2 µs, ~5×).
  • DefaultFinder (preindex + polygon) consistently wins for general workloads: ~1 µs median with ~75–126 MB memory, regardless of dataset.
  • FuzzyFinder (preindex only) is the fastest at ~470 ns, but only covers tiles that lie entirely within a single timezone polygon. For points near borders or outside covered tiles it returns no result rather than guessing. Only use it standalone if your workload is known to be well away from timezone borders.
  • Python (tzfpy) adds ~0.5–1 µs of PyO3 FFI overhead on top of the Rust baseline. With YStripes enabled the median sits at ~1.8 µs — well within the range of most backend API budgets.
  • Memory scales with dataset: switching from topology-simplified to full-precision in Rust adds roughly 450 MB with YStripes enabled.
Last updated on