コンテンツにスキップ

ベンチマーク

目的の異なる 2 つのベンチマークセットアップがあります。

継続的ベンチマーク:ソースと結果は https://github.com/ringsaturn/tz-benchmark、可視化は https://ringsaturn.github.io/tz-benchmark/ にあります。各リリース時に GitHub Actions で実行され、パッケージ間の比較を行います。ランナーのハードウェアは開発マシンと異なるため、絶対値はローカル実行と異なりますが、パッケージ間の相対的な順序は比較できます。継続的ベンチマークは 2026-09-11 以降 tzf v2 を対象にしています。

日付付きスナップショットsnapshot/ 以下のディレクトリは Apple M3 Max 上でローカルに取得されたものです。このページの内容はすべて 2026-09-14 のスナップショットによるもので、公開された tzf v2.1.1、tzf-rs 2.1.1、および tzfpy 2.1.0b2 プレリリース(lite と +full の wheel)を対象に、いずれも tzf-dist v0.0.2026-c-tzb2 上で測定されています。

測定方法

各 Finder は一度初期化され、すべてのクエリで再利用されます。これはドキュメントに記載された本番環境のパターンと一致します。クエリは 2 つのデータセットをサンプルします。154,694 件の世界都市(gt_cities.csv)と、境界に隣接する 23,408 件の地点(gt_edges.csv)で、いずれも完全精度の 2026c 正解データと照合します。精度検証では、Go において 1,000,000 点の一様乱数データセットも実行します。

メモリは候補ごとに隔離された子プロセスで測定します。以下では 4 つの列が登場し、これらは互換ではありません。

意味
ベースライン候補を構築する前の RSS
初期化ピークロード中に到達する高水位(ru_maxrss)。コンテナのメモリ上限はこの値を収容できる必要があります。そうでなければ、定常状態なら収まるはずのプロセスが起動時に kill されます
常駐候補がクエリを処理できる状態になった後に保持しているデータ量。言語ネイティブの計測(Go は強制 GC 後の HeapAlloc、Rust はカウント機能付きグローバルアロケータ)によります。差分ではなく絶対値です。Python は Python ヒープの外にデータを保持するため n/a です
ロード後 RSSクエリを処理できる状態のプロセスについて OS が報告する値。常駐 より 初期化ピーク に近くなります。メモリを解放しても RSS は縮まず、アロケータがページをカーネルに返さず再利用のために保持し続けるためです

すべての候補で 常駐 <= ロード後 RSS <= 初期化ピーク の関係が成り立ちます。

クエリレイテンシ

Apple M3 Max、2026c データセット、2026-09-14 スナップショット。

Go (tzf v2)

ベンチマークns/opp50 (ns)p99 (ns)B/opallocs/op
NewDefaultFinder、世界都市345.8208.0150000
NewDefaultFinder、境界都市543.7459.0120800
NewEmbeddedFinder、世界都市533.7333.0250000
NewEmbeddedFinder、境界都市11621000279100
NewFullFinder、世界都市347.9208.0158300
NewFullFinder、境界都市606.7500.0175000

3 つの Finder はいずれもアロケーションなしでクエリを処理します。

Rust (tzf-rs 2.1)

ベンチマークns/iter標準偏差 (ns)
DefaultFinder、ランダム都市221.1341.39
DefaultFinder、ランダム境界都市474.8352.12
EmbeddedFinder、ランダム都市292.6851.42
EmbeddedFinder、ランダム境界都市666.1148.17

Python (tzfpy 2.1.0b2)

pytest-benchmark を使用し、1 ラウンドあたり get_tz() を 1 回呼び出します。

ベンチマーク中央値 (ns)平均 (ns)OPS (Kops/s)
ランダム都市、lite625.0718.71,391.4
ランダム境界都市、lite834.0907.01,102.5
ランダム都市、+full667.0822.71,215.5
ランダム境界都市、+full1,167.01,292.3773.8

呼び出しあたりのオーバーヘッドは Rust の数値と同程度であり、差分は PyO3 を経由した Python から Rust への呼び出しコストによるものです。+full の行は tzfpy 独自のインデックスから配布される実験的な完全精度 wheel で、tzf-rs の EmbeddedFinderfull.tzb を参照します。

精度

完全精度の 2026c 正解データに対する誤答率です。「オフセット一致」は、誤答のうち UTC オフセットが同じものの件数です。

データセットN候補誤答誤答率 %オフセット一致
cities154,694Go NewDefaultFinder(lite .tzm10.00061
cities154,694Go NewEmbeddedFinder(lite .tzb10.00061
cities154,694Go NewFullFinder(full .tzb00.00000
cities154,694Rust DefaultFinder10.00061
cities154,694Rust EmbeddedFinder10.00061
cities154,694tzfpy10.00061
cities154,694tzfpy +full00.00000
edges23,408Go NewDefaultFinder(lite .tzm10.00431
edges23,408Go NewFullFinder(full .tzb00.00000
edges23,408Rust DefaultFinder10.00431
edges23,408tzfpy10.00431
edges23,408tzfpy +full00.00000
uniform1,000,000Go NewDefaultFinder(lite .tzm190.001914
uniform1,000,000Go NewFullFinder(full .tzb00.00000

lite と full の Finder が異なる結果を返すのは境界付近のみです。簡略化による変位の上限は 111.2 m です。変位の詳細な表はよくある質問を参照してください。

メモリ

単位は MiB です。

Go

候補ベースライン初期化ピーク常駐ロード後 RSS
Go ランタイムの下限値4.74.70.25.0
NewDefaultFinder(lite .tzm5.141.513.141.5
NewEmbeddedFinder(lite .tzb をインプレースで参照)5.29.20.39.6
NewFullFinder(full .tzb5.2315.5147.0315.5

Rust

候補ベースライン初期化ピーク常駐ロード後 RSS
Rust ランタイムの下限値5.85.90.05.9
DefaultFinder5.846.622.846.5
EmbeddedFinder5.810.30.210.4

EmbeddedFinder の常駐は 0.2 MiB です。データは 'static の埋め込みスライスであり、カウント機能付きアロケータが検出するのは tzf-rs 2.1 がオープン時に構築するインデックス(チャンクのスキップブロックとグループごとの緯度ストライプ)のみです。

Python

候補ベースライン初期化ピーク常駐ロード後 RSS
Python インタプリタの下限値22.422.4n/a22.4
tzfpy(lite)22.460.3n/a60.2
tzfpy +full22.438.2n/a38.2

観察結果

  • インプレース方式はクエリレイテンシとメモリのトレードオフです。Go では初期化ピークが 41.5 MiB から 9.2 MiB に下がる一方、世界都市の中央値は 208 ns から 333 ns、境界都市の中央値は 459 ns から 1,000 ns に上がります。
  • 2026-09-11 のスナップショットと比べると、インプレース方式の境界都市の値は Go の p50 で 8,959 ns から 1,000 ns、Rust の平均で 4,779.81 ns から 666.11 ns に下がりました。要因は tzf 2.1 と tzf-rs 2.1 のクエリ走査の書き直し、および v0.0.2026-c-tzb2 の 64 点チャンクです。展開方式の Finder はノイズの範囲内で変化なし、結果は同一です。
  • tzfpy +full プレリリースの境界都市の中央値は 1,167 ns(lite wheel は 834 ns)、初期化ピークは 38.2 MiB(lite wheel は 60.3 MiB)です。
  • 完全精度データセットのコストはレイテンシではなくメモリに現れます。Go の初期化ピークは 41.5 MiB から 315.5 MiB に増加しますが、世界都市の中央値は 208 ns のままです。
  • 初期化ピークは定常状態のコストを過大に示します。Go のデフォルト Finder はピーク 41.5 MiB に対して常駐 13.1 MiB、完全精度 Finder はピーク 315.5 MiB に対して常駐 147.0 MiB です。コンテナのメモリはピークに合わせ、長期運用のコストは常駐値で見積もってください。
  • 言語ランタイムの下限値は異なるため(Go 4.7 MiB、Rust 5.8 MiB、Python 22.4 MiB)、言語間で合計値を比較する際はこれらを差し引く必要があります。
  • lite データセットが完全精度の正解データと異なる結果を返すのは 154,694 件の世界都市のうち 1 件で、その結果も UTC オフセットは同じです。
最終更新日