コンテンツにスキップ

ベンチマーク

目的の異なる 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-11-01 のスナップショットによるもので、公開された tzf v2.1.4、tzf-rs 2.1.4、tzfpy 2.1.2(lite と +full の wheel)を対象に、いずれも tzf-dist v0.0.2026-f 上で測定されています。

測定方法

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

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

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

すべての候補で 常駐 が 3 つの値のうち最小です。ロード後 RSS が 初期化ピーク を上回る幅は最大 0.5 MiB です。

クエリレイテンシ

Apple M3 Max、2026f データセット、2026-11-01 スナップショット。

Go (tzf v2)

ベンチマークns/opp50 (ns)p99 (ns)B/opallocs/op
NewDefaultFinder、世界都市350.0208.0150000
NewDefaultFinder、境界都市556.5500.0125000
NewEmbeddedFinder、世界都市535.8333.0254200
NewEmbeddedFinder、境界都市12301042275000
NewFullFinder、世界都市354.5208.0170800
NewFullFinder、境界都市591.8500.0154200

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

Rust (tzf-rs 2.1.4)

ベンチマークns/iter標準偏差 (ns)
DefaultFinder、ランダム都市225.6221.17
DefaultFinder、ランダム境界都市489.3310.13
EmbeddedFinder、ランダム都市350.34110.85
EmbeddedFinder、ランダム境界都市686.948.99

Python (tzfpy 2.1.2)

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

ベンチマーク中央値 (ns)平均 (ns)OPS (Kops/s)
ランダム都市、lite666.0745.41,341.6
ランダム境界都市、lite875.0958.81,042.9
ランダム都市、+full667.0810.51,233.8
ランダム境界都市、+full1,208.01,313.5761.4

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

精度

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

データセットN候補誤答誤答率 %オフセット一致
cities170,540Go NewDefaultFinder(lite .tzm)20.00121
cities170,540Go NewEmbeddedFinder(lite .tzb)20.00121
cities170,540Go NewFullFinder(full .tzb)00.00000
cities170,540Rust DefaultFinder20.00121
cities170,540Rust EmbeddedFinder20.00121
cities170,540tzfpy20.00121
cities170,540tzfpy +full00.00000
edges23,408Go NewDefaultFinder(lite .tzm)10.00431
edges23,408Go NewFullFinder(full .tzb)00.00000
edges23,408Rust DefaultFinder10.00431
edges23,408tzfpy10.00431
edges23,408tzfpy +full00.00000
uniform1,000,000Go NewDefaultFinder(lite .tzm)210.002114
uniform1,000,000Go NewFullFinder(full .tzb)00.00000

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

メモリ

単位は MiB です。

Go

候補ベースライン初期化ピーク常駐ロード後 RSS
Go ランタイムの下限値5.15.10.35.4
NewDefaultFinder(lite .tzm)5.544.513.344.6
NewEmbeddedFinder(lite .tzb をインプレースで参照)5.79.60.410.1
NewFullFinder(full .tzb)5.7266.7148.9266.9

Rust

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

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

Python

候補ベースライン初期化ピーク常駐ロード後 RSS
Python インタプリタの下限値22.522.5n/a22.5
tzfpy(lite)22.561.3n/a61.2
tzfpy +full22.538.8n/a38.8

観察結果

  • インプレース方式はクエリレイテンシとメモリのトレードオフです。Go では初期化ピークが 44.5 MiB から 9.6 MiB に下がる一方、世界都市の中央値は 208 ns から 333 ns、境界都市の中央値は 500 ns から 1,042 ns に上がります。
  • 2026-09-14 のスナップショット(tzf v2.1.1、2026c)と比べると、Go の世界都市の中央値は 208、333、208 ns で変わらず、Go の境界都市の中央値の差は最大 42 ns です。Rust の EmbeddedFinder のランダム都市の平均は 292.68 ns から 350.34 ns に上がり、今回の標準偏差は 110.85 ns です。Go の NewFullFinder の初期化ピークは 315.5 MiB から 266.7 MiB に下がり、常駐ヒープは約 148 MiB のままです。初期化ピークが変化した原因は確認されていません。
  • tz-benchmark が 2026-09-20 に正解データを更新したため、世界都市データセットは 154,694 件から 170,540 件に増えました。精度の件数は 2026-09-14 の表と直接比較できません。
  • tzfpy +full wheel の境界都市の中央値は 1,208 ns(lite wheel は 875 ns)、初期化ピークは 38.8 MiB(lite wheel は 61.3 MiB)です。
  • 完全精度データセットのコストはレイテンシではなくメモリに現れます。Go の初期化ピークは 44.5 MiB から 266.7 MiB に増加しますが、世界都市の中央値は 208 ns のままです。
  • 初期化ピークは定常状態のコストを過大に示します。Go のデフォルト Finder はピーク 44.5 MiB に対して常駐 13.3 MiB、完全精度 Finder はピーク 266.7 MiB に対して常駐 148.9 MiB です。コンテナのメモリはピークに合わせ、長期運用のコストは常駐値で見積もってください。
  • 言語ランタイムの下限値は異なるため(Go 5.1 MiB、Rust 5.8 MiB、Python 22.5 MiB)、言語間で合計値を比較する際はこれらを差し引く必要があります。
  • lite データセットが完全精度の正解データと異なる結果を返すのは 170,540 件の世界都市のうち 2 件で、ハーネスはそのうち 1 件を UTC オフセットが同じ結果として数えています。
最終更新日