mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
feat: O_AMMR_valid strengthened + hash benchmark complete
NS_MD.lean: - Added QRResidualWitness structure (Q16_16 fixed-point) - Added residual_bound_ok, basis_size_ok, orthogonality_ok predicates - Extended O_AMMR_Node with qr_witness field - Strengthened O_AMMR_valid: 4 conjuncts (admission + residual + basis + ortho) - lake build: 3300 jobs, 0 errors hash_benchmark.py (240 data points): - Hilbert vs Morton vs xxHash - 5 grid sizes (16^3 to 256^3), 4 trace sizes, 4 patterns Key findings: Morton: 86.5% cache hit rate, 1.08µs p50, 0.512 locality xxHash: 30.3% cache hit rate, 0.96µs p50, 0.342 locality Hilbert: 27.6% cache hit rate, 2.29µs p50, 0.833 locality Morton wins overall for spatial hash grids.
This commit is contained in:
parent
9380eb3449
commit
3dace5fe73
4 changed files with 3456 additions and 5 deletions
|
|
@ -90,10 +90,9 @@ def dotProduct (a b : List Int) : Int :=
|
|||
(List.zip a b).foldl (fun acc (x, y) => acc + x * y) 0
|
||||
|
||||
def is_epsilon_orthogonal (qi qj : List Int) (epsilon : Int) : Prop :=
|
||||
let d := dotProduct qi qj
|
||||
-epsilon < d ∧ d < epsilon
|
||||
(-epsilon < dotProduct qi qj) ∧ (dotProduct qi qj < epsilon)
|
||||
|
||||
/-- #eval witness: orthogonal vectors have zero dot product -/
|
||||
/- Witness: orthogonal vectors have zero dot product -/
|
||||
#eval let v1 : List Int := [1, 2, 3]
|
||||
let v2 : List Int := [1, -2, 1]
|
||||
dotProduct v1 v2
|
||||
|
|
@ -129,14 +128,56 @@ def admit (g : GoxelAdmission) (epsilon_g epsilon_pi budget : Nat) : Prop :=
|
|||
g.kot_cost ≤ budget ∧
|
||||
g.audit_bundle == "valid"
|
||||
|
||||
/-- O-AMMR Node Validity Predicate (Goxel-Aware). -/
|
||||
/-- QR Factorization Witness: carries pre-computed QR validation data.
|
||||
All values are Q16_16 fixed-point; no Float in compute paths.
|
||||
The witness is produced by the QR factorization runtime and
|
||||
consumed by the formal validation predicate. -/
|
||||
structure QRResidualWitness where
|
||||
residual_norm : Semantics.FixedPoint.Q16_16 -- pre-computed ||A - QR|| (Frobenius or max-norm)
|
||||
epsilon_residual : Semantics.FixedPoint.Q16_16 -- tolerance for residual bound
|
||||
basis_size : Nat -- number of QR columns
|
||||
max_basis : Nat -- rank control: basis_size ≤ max_basis
|
||||
ortho_violation : Semantics.FixedPoint.Q16_16 -- max |q_i · q_j| over i ≠ j (off-diagonal)
|
||||
epsilon_ortho : Semantics.FixedPoint.Q16_16 -- tolerance for orthogonality
|
||||
deriving Repr
|
||||
|
||||
/-- Residual bound check: ||A - QR|| < ε in Q16_16 fixed-point.
|
||||
This is a Prop-level predicate formalizing that the QR factorization
|
||||
residual is within the accepted tolerance. -/
|
||||
def residual_bound_ok (w : QRResidualWitness) : Prop :=
|
||||
(Semantics.FixedPoint.Q16_16.abs w.residual_norm).toInt < w.epsilon_residual.toInt
|
||||
|
||||
/-- Basis size check: basis_size ≤ max_basis (rank control). -/
|
||||
def basis_size_ok (w : QRResidualWitness) : Prop :=
|
||||
w.basis_size ≤ w.max_basis
|
||||
|
||||
/-- Orthogonality check: Q^T Q ≈ I within Q16_16 tolerance.
|
||||
The maximum off-diagonal dot product must be below ε. -/
|
||||
def orthogonality_ok (w : QRResidualWitness) : Prop :=
|
||||
(Semantics.FixedPoint.Q16_16.abs w.ortho_violation).toInt < w.epsilon_ortho.toInt
|
||||
|
||||
/-- O-AMMR Node Validity Predicate (QR-Hardened).
|
||||
Validates both the admission gate and the QR factorization witness.
|
||||
Three independent checks must all pass:
|
||||
1. Residual bound: ||A - QR|| < ε_residual
|
||||
2. Basis size: basis_size ≤ max_basis
|
||||
3. Orthogonality: max off-diagonal |q_i · q_j| < ε_ortho -/
|
||||
structure O_AMMR_Node where
|
||||
hash_committed : String
|
||||
admission : GoxelAdmission
|
||||
qr_witness : QRResidualWitness
|
||||
deriving Repr
|
||||
|
||||
/-- The strengthened O_AMMR_valid predicate. Requires:
|
||||
(a) admission gate: ρ_G ≤ ε_G ∧ ρ_Π ≤ ε_Π ∧ KOT ≤ budget ∧ audit = valid
|
||||
(b) QR residual bound: ||A - QR|| < ε_residual
|
||||
(c) basis size: basis_size ≤ max_basis
|
||||
(d) orthogonality: max off-diagonal |q_i · q_j| < ε_ortho -/
|
||||
def O_AMMR_valid (node : O_AMMR_Node) (eg epi b : Nat) : Prop :=
|
||||
admit node.admission eg epi b
|
||||
admit node.admission eg epi b ∧
|
||||
residual_bound_ok node.qr_witness ∧
|
||||
basis_size_ok node.qr_witness ∧
|
||||
orthogonality_ok node.qr_witness
|
||||
|
||||
/-- Projection function: interprets a GCCL-Rep event for a specific mountain. -/
|
||||
def project (_rep : GCCLByteRepresentative) (m : Mountain) : Prop :=
|
||||
|
|
|
|||
491
4-Infrastructure/shim/hash_benchmark.py
Normal file
491
4-Infrastructure/shim/hash_benchmark.py
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Hash Function Benchmark: Hilbert vs Morton vs xxHash
|
||||
|
||||
Benchmarks three spatial hashing strategies across multiple grid sizes and
|
||||
access pattern traces. Measures cache hit rate, lookup latency (p50/p99),
|
||||
spatial locality preservation, and simulated memory bandwidth.
|
||||
|
||||
Output:
|
||||
- CSV: /home/allaun/Research Stack/shared-data/artifacts/hash_benchmark.csv
|
||||
- JSON: /home/allaun/Research Stack/shared-data/artifacts/hash_benchmark.json
|
||||
"""
|
||||
|
||||
import csv
|
||||
import hashlib
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
from collections import OrderedDict
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
import xxhash
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
# 1. HASH FUNCTIONS
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
def _part1by1(n: int) -> int:
|
||||
"""Spread bits of a 16-bit integer so every bit is separated by a zero."""
|
||||
n &= 0x0000FFFF
|
||||
n = (n | (n << 8)) & 0x00FF00FF
|
||||
n = (n | (n << 4)) & 0x0F0F0F0F
|
||||
n = (n | (n << 2)) & 0x33333333
|
||||
n = (n | (n << 1)) & 0x55555555
|
||||
return n
|
||||
|
||||
def _unpart1by1(n: int) -> int:
|
||||
n &= 0x55555555
|
||||
n = (n | (n >> 1)) & 0x33333333
|
||||
n = (n | (n >> 2)) & 0x0F0F0F0F
|
||||
n = (n | (n >> 4)) & 0x00FF00FF
|
||||
n = (n | (n >> 8)) & 0x0000FFFF
|
||||
return n
|
||||
|
||||
# ---------- Morton code ----------
|
||||
|
||||
def morton_encode_2d(x: int, y: int) -> int:
|
||||
return _part1by1(x) | (_part1by1(y) << 1)
|
||||
|
||||
def morton_decode_2d(n: int) -> Tuple[int, int]:
|
||||
return _unpart1by1(n), _unpart1by1(n >> 1)
|
||||
|
||||
def morton_encode_3d(x: int, y: int, z: int) -> int:
|
||||
def spread(v):
|
||||
v &= 0x000003FF
|
||||
v = (v | (v << 16)) & 0xFF0000FF
|
||||
v = (v | (v << 8)) & 0x0300F00F
|
||||
v = (v | (v << 4)) & 0x30C30C30
|
||||
v = (v | (v << 2)) & 0x92492492
|
||||
return v
|
||||
return spread(x) | (spread(y) << 1) | (spread(z) << 2)
|
||||
|
||||
def morton_decode_3d(n: int) -> Tuple[int, int, int]:
|
||||
def compact(v):
|
||||
v &= 0x92492492
|
||||
v = (v | (v >> 2)) & 0x30C30C30
|
||||
v = (v | (v >> 4)) & 0x0300F00F
|
||||
v = (v | (v >> 8)) & 0xFF0000FF
|
||||
v = (v | (v >> 16)) & 0x000003FF
|
||||
return v
|
||||
return compact(n), compact(n >> 1), compact(n >> 2)
|
||||
|
||||
# ---------- Hilbert curve ----------
|
||||
|
||||
def _hilbert_index_to_point_2d(n: int, d: int) -> Tuple[int, int]:
|
||||
"""Convert Hilbert index *n* to 2D point for order *d* (side = 2^d)."""
|
||||
x = y = 0
|
||||
s = 1 << (d - 1)
|
||||
for _ in range(d):
|
||||
rx = (n >> 1) & 1
|
||||
ry = (n ^ rx) & 1
|
||||
if ry == 0:
|
||||
if rx == 1:
|
||||
x = s - 1 - x
|
||||
y = s - 1 - y
|
||||
x, y = y, x
|
||||
x += s * rx
|
||||
y += s * ry
|
||||
n >>= 2
|
||||
s >>= 1
|
||||
return x, y
|
||||
|
||||
def _hilbert_point_to_index_2d(x: int, y: int, d: int) -> int:
|
||||
"""Convert 2D point to Hilbert index for order *d*."""
|
||||
n = 0
|
||||
s = 1 << (d - 1)
|
||||
for _ in range(d):
|
||||
rx = 1 if (x & s) else 0
|
||||
ry = 1 if (y & s) else 0
|
||||
n += s * s * ((3 * rx) ^ ry)
|
||||
if ry == 0:
|
||||
if rx == 1:
|
||||
x = s - 1 - x
|
||||
y = s - 1 - y
|
||||
x, y = y, x
|
||||
x -= s * rx
|
||||
y -= s * ry
|
||||
s >>= 1
|
||||
return n
|
||||
|
||||
def _hilbert_index_to_point_3d(n: int, d: int) -> Tuple[int, int, int]:
|
||||
"""Convert Hilbert index to 3D point for order d."""
|
||||
x = y = z = 0
|
||||
s = 1 << (d - 1)
|
||||
for _ in range(d):
|
||||
rx = (n >> 2) & 1
|
||||
ry = (n >> 1) & 1
|
||||
rz = (n ^ rx ^ ry) & 1
|
||||
# inverse Gray code
|
||||
if rz == 0:
|
||||
if rx == 1:
|
||||
x = s - 1 - x
|
||||
y = s - 1 - y
|
||||
if ry == 1:
|
||||
z_temp = z
|
||||
z = s - 1 - y
|
||||
y = s - 1 - z_temp
|
||||
x, y, z = y, z, x
|
||||
else:
|
||||
if ry == 1:
|
||||
z_temp = z
|
||||
z = s - 1 - y
|
||||
y = s - 1 - z_temp
|
||||
if rx == 1:
|
||||
x = s - 1 - x
|
||||
y = s - 1 - y
|
||||
x, y, z = z, x, y
|
||||
x += s * rx
|
||||
y += s * ry
|
||||
z += s * rz
|
||||
n >>= 3
|
||||
s >>= 1
|
||||
return x, y, z
|
||||
|
||||
def _hilbert_point_to_index_3d(x: int, y: int, z: int, d: int) -> int:
|
||||
"""Convert 3D point to Hilbert index for order d."""
|
||||
n = 0
|
||||
s = 1 << (d - 1)
|
||||
for _ in range(d):
|
||||
rx = 1 if (x & s) else 0
|
||||
ry = 1 if (y & s) else 0
|
||||
rz = 1 if (z & s) else 0
|
||||
n += s * s * s * ((7 * rx) ^ (3 * ry) ^ rz)
|
||||
if rz == 0:
|
||||
if ry == 1:
|
||||
z_temp = z
|
||||
z = s - 1 - y
|
||||
y = s - 1 - z_temp
|
||||
if rx == 1:
|
||||
x = s - 1 - x
|
||||
y = s - 1 - y
|
||||
x, y, z = y, z, x
|
||||
else:
|
||||
x, y, z = z, x, y
|
||||
if ry == 1:
|
||||
z_temp = z
|
||||
z = s - 1 - y
|
||||
y = s - 1 - z_temp
|
||||
if rx == 1:
|
||||
x = s - 1 - x
|
||||
y = s - 1 - y
|
||||
x -= s * rx
|
||||
y -= s * ry
|
||||
z -= s * rz
|
||||
s >>= 1
|
||||
return n
|
||||
|
||||
def hilbert_encode(x: int, y: int, z: int, order: int) -> int:
|
||||
return _hilbert_point_to_index_3d(x, y, z, order)
|
||||
|
||||
def hilbert_decode(n: int, order: int) -> Tuple[int, int, int]:
|
||||
return _hilbert_index_to_point_3d(n, order)
|
||||
|
||||
# ---------- xxHash wrapper ----------
|
||||
|
||||
def xxhash_encode(x: int, y: int, z: int, grid_size: int) -> int:
|
||||
"""Hash 3D coordinates using xxHash, mapped into [0, grid_size^3)."""
|
||||
data = struct_pack_3ints(x, y, z)
|
||||
h = xxhash.xxh3_64(data).intdigest()
|
||||
return h % (grid_size ** 3)
|
||||
|
||||
def _struct_pack_3ints(x: int, y: int, z: int) -> bytes:
|
||||
return x.to_bytes(4, 'little') + y.to_bytes(4, 'little') + z.to_bytes(4, 'little')
|
||||
|
||||
# alias
|
||||
struct_pack_3ints = _struct_pack_3ints
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
# 2. ACCESS PATTERN TRACES
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
def trace_sequential(grid_size: int, n: int) -> List[Tuple[int, int, int]]:
|
||||
"""Linear scan through the entire grid in row-major order."""
|
||||
coords = []
|
||||
for i in range(min(n, grid_size ** 3)):
|
||||
z = i // (grid_size * grid_size)
|
||||
rem = i % (grid_size * grid_size)
|
||||
y = rem // grid_size
|
||||
x = rem % grid_size
|
||||
coords.append((x, y, z))
|
||||
# tile if n > total cells
|
||||
while len(coords) < n:
|
||||
coords.extend(coords[:n - len(coords)])
|
||||
return coords[:n]
|
||||
|
||||
def trace_random(grid_size: int, n: int) -> List[Tuple[int, int, int]]:
|
||||
"""Uniformly random coordinates."""
|
||||
rng = random.Random(42)
|
||||
return [(rng.randint(0, grid_size - 1),
|
||||
rng.randint(0, grid_size - 1),
|
||||
rng.randint(0, grid_size - 1)) for _ in range(n)]
|
||||
|
||||
def trace_spatial_locality(grid_size: int, n: int) -> List[Tuple[int, int, int]]:
|
||||
"""Random walk with small steps — simulates spatial locality."""
|
||||
rng = random.Random(42)
|
||||
x, y, z = grid_size // 2, grid_size // 2, grid_size // 2
|
||||
coords = []
|
||||
for _ in range(n):
|
||||
coords.append((x, y, z))
|
||||
dx = rng.randint(-3, 3)
|
||||
dy = rng.randint(-3, 3)
|
||||
dz = rng.randint(-3, 3)
|
||||
x = max(0, min(grid_size - 1, x + dx))
|
||||
y = max(0, min(grid_size - 1, y + dy))
|
||||
z = max(0, min(grid_size - 1, z + dz))
|
||||
return coords
|
||||
|
||||
def trace_temporal_locality(grid_size: int, n: int) -> List[Tuple[int, int, int]]:
|
||||
"""Repeated access to a recent working set."""
|
||||
rng = random.Random(42)
|
||||
window = max(16, n // 20)
|
||||
recent: List[Tuple[int, int, int]] = []
|
||||
coords = []
|
||||
for i in range(n):
|
||||
if recent and rng.random() < 0.7:
|
||||
c = rng.choice(recent)
|
||||
else:
|
||||
c = (rng.randint(0, grid_size - 1),
|
||||
rng.randint(0, grid_size - 1),
|
||||
rng.randint(0, grid_size - 1))
|
||||
coords.append(c)
|
||||
recent.append(c)
|
||||
if len(recent) > window:
|
||||
recent.pop(0)
|
||||
return coords
|
||||
|
||||
TRACE_GENERATORS = {
|
||||
"sequential": trace_sequential,
|
||||
"random": trace_random,
|
||||
"spatial_locality": trace_spatial_locality,
|
||||
"temporal_locality": trace_temporal_locality,
|
||||
}
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
# 3. SIMULATED CACHE
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
class SimCache:
|
||||
"""LRU set-associative cache simulation (3 levels: L1/L2/L3)."""
|
||||
|
||||
def __init__(self, l1_lines=64, l2_lines=512, l3_lines=4096):
|
||||
self.l1 = OrderedDict()
|
||||
self.l2 = OrderedDict()
|
||||
self.l3 = OrderedDict()
|
||||
self.l1_cap = l1_lines
|
||||
self.l2_cap = l2_lines
|
||||
self.l3_cap = l3_lines
|
||||
self.hits = 0
|
||||
self.misses = 0
|
||||
|
||||
def access(self, key: int) -> str:
|
||||
if key in self.l1:
|
||||
self.l1.move_to_end(key)
|
||||
self.hits += 1
|
||||
return "L1"
|
||||
if key in self.l2:
|
||||
self.l2.move_to_end(key)
|
||||
self.l1[key] = True
|
||||
if len(self.l1) > self.l1_cap:
|
||||
self.l1.popitem(last=False)
|
||||
self.hits += 1
|
||||
return "L2"
|
||||
if key in self.l3:
|
||||
self.l3.move_to_end(key)
|
||||
self.l2[key] = True
|
||||
if len(self.l2) > self.l2_cap:
|
||||
self.l2.popitem(last=False)
|
||||
self.l1[key] = True
|
||||
if len(self.l1) > self.l1_cap:
|
||||
self.l1.popitem(last=False)
|
||||
self.hits += 1
|
||||
return "L3"
|
||||
# miss
|
||||
self.l3[key] = True
|
||||
if len(self.l3) > self.l3_cap:
|
||||
self.l3.popitem(last=False)
|
||||
self.l2[key] = True
|
||||
if len(self.l2) > self.l2_cap:
|
||||
self.l2.popitem(last=False)
|
||||
self.l1[key] = True
|
||||
if len(self.l1) > self.l1_cap:
|
||||
self.l1.popitem(last=False)
|
||||
self.misses += 1
|
||||
return "MISS"
|
||||
|
||||
def hit_rate(self) -> float:
|
||||
total = self.hits + self.misses
|
||||
return self.hits / total if total else 0.0
|
||||
|
||||
def reset(self):
|
||||
self.l1.clear(); self.l2.clear(); self.l3.clear()
|
||||
self.hits = 0; self.misses = 0
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
# 4. SPATIAL LOCALITY PRESERVATION METRIC
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
def locality_preservation(coords: List[Tuple[int, int, int]],
|
||||
hashes: List[int]) -> float:
|
||||
"""
|
||||
Fraction of spatially-adjacent points (Manhattan dist <= 1) whose
|
||||
hash indices differ by at most grid_size (roughly one grid plane).
|
||||
"""
|
||||
if len(coords) < 2:
|
||||
return 1.0
|
||||
adjacent = 0
|
||||
preserved = 0
|
||||
sample = min(len(coords), 2000)
|
||||
rng = random.Random(99)
|
||||
indices = rng.sample(range(len(coords)), sample)
|
||||
grid_size_approx = int(round(len(hashes) ** (1/3))) if len(hashes) > 0 else 64
|
||||
threshold = grid_size_approx # one "row" in linearised grid
|
||||
for i in indices:
|
||||
for j in indices:
|
||||
if j <= i:
|
||||
continue
|
||||
cx, cy, cz = coords[i]
|
||||
dx, dy, dz = coords[j]
|
||||
manhattan = abs(cx - dx) + abs(cy - dy) + abs(cz - dz)
|
||||
if manhattan <= 1:
|
||||
adjacent += 1
|
||||
if abs(hashes[i] - hashes[j]) <= threshold:
|
||||
preserved += 1
|
||||
return preserved / adjacent if adjacent > 0 else 1.0
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
# 5. BENCHMARK RUNNER
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
def run_benchmark():
|
||||
grid_sizes = [16, 32, 64, 128, 256]
|
||||
trace_sizes = [1000, 10000, 100000, 1000000]
|
||||
results = []
|
||||
|
||||
for gs in grid_sizes:
|
||||
order = int(math.log2(gs))
|
||||
for tn in trace_sizes:
|
||||
for tname, tgen in TRACE_GENERATORS.items():
|
||||
trace = tgen(gs, tn)
|
||||
for hname in ("hilbert", "morton", "xxhash"):
|
||||
cache = SimCache()
|
||||
latencies = []
|
||||
hashes_out = []
|
||||
|
||||
t0 = time.perf_counter_ns()
|
||||
for (x, y, z) in trace:
|
||||
if hname == "hilbert":
|
||||
h = hilbert_encode(x, y, z, order)
|
||||
elif hname == "morton":
|
||||
h = morton_encode_3d(x, y, z)
|
||||
else:
|
||||
h = xxhash_encode(x, y, z, gs)
|
||||
hashes_out.append(h)
|
||||
cache.access(h)
|
||||
t1 = time.perf_counter_ns()
|
||||
latencies.append(t1 - t0)
|
||||
t0 = t1
|
||||
|
||||
# percentiles
|
||||
latencies.sort()
|
||||
n = len(latencies)
|
||||
p50 = latencies[n // 2] / 1e3 # µs
|
||||
p99 = latencies[int(n * 0.99)] / 1e3
|
||||
total_ns = sum(latencies)
|
||||
bandwidth = (tn * 12) / (total_ns / 1e9) / 1e6 # MB/s (12 bytes/coord)
|
||||
|
||||
loc = locality_preservation(trace, hashes_out)
|
||||
|
||||
row = OrderedDict(
|
||||
grid_size=gs,
|
||||
trace_size=tn,
|
||||
trace_pattern=tname,
|
||||
hash_function=hname,
|
||||
cache_hit_rate=round(cache.hit_rate(), 6),
|
||||
p50_latency_us=round(p50, 4),
|
||||
p99_latency_us=round(p99, 4),
|
||||
memory_bandwidth_mbs=round(bandwidth, 2),
|
||||
locality_preservation=round(loc, 6),
|
||||
)
|
||||
results.append(row)
|
||||
print(f" gs={gs:>4d} trace={tn:>7d} {tname:<18s} {hname:<8s} "
|
||||
f"hit={cache.hit_rate():.3f} p50={p50:.2f}µs p99={p99:.2f}µs "
|
||||
f"bw={bandwidth:.1f}MB/s loc={loc:.3f}")
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def write_outputs(results: List[OrderedDict]):
|
||||
base = Path("/home/allaun/Research Stack/shared-data/artifacts")
|
||||
base.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# CSV
|
||||
csv_path = base / "hash_benchmark.csv"
|
||||
with open(csv_path, "w", newline="") as f:
|
||||
w = csv.DictWriter(f, fieldnames=results[0].keys())
|
||||
w.writeheader()
|
||||
w.writerows(results)
|
||||
print(f"\nCSV → {csv_path}")
|
||||
|
||||
# JSON
|
||||
json_path = base / "hash_benchmark.json"
|
||||
payload = {
|
||||
"benchmark": "hash_function_comparison",
|
||||
"description": "Hilbert vs Morton vs xxHash spatial hashing benchmark",
|
||||
"grid_sizes": [16, 32, 64, 128, 256],
|
||||
"trace_sizes": [1000, 10000, 100000, 1000000],
|
||||
"hash_functions": ["hilbert", "morton", "xxhash"],
|
||||
"trace_patterns": ["sequential", "random", "spatial_locality", "temporal_locality"],
|
||||
"metrics": ["cache_hit_rate", "p50_latency_us", "p99_latency_us",
|
||||
"memory_bandwidth_mbs", "locality_preservation"],
|
||||
"generated_at": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
|
||||
"results": results,
|
||||
}
|
||||
with open(json_path, "w") as f:
|
||||
json.dump(payload, f, indent=2)
|
||||
print(f"JSON → {json_path}")
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
# 6. SUMMARY TABLE
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
def print_summary(results: List[OrderedDict]):
|
||||
from itertools import groupby
|
||||
|
||||
print("\n" + "=" * 90)
|
||||
print("AGGREGATE SUMMARY (averaged across grid sizes and trace sizes)")
|
||||
print("=" * 90)
|
||||
print(f"{'Hash':<10s} {'Pattern':<20s} {'Avg Hit%':>9s} {'Avg p50µs':>10s} "
|
||||
f"{'Avg p99µs':>10s} {'Avg BW MB/s':>12s} {'Avg Loc':>8s}")
|
||||
print("-" * 90)
|
||||
|
||||
key_fn = lambda r: (r["hash_function"], r["trace_pattern"])
|
||||
results_sorted = sorted(results, key=key_fn)
|
||||
for (hf, tp), group in groupby(results_sorted, key=key_fn):
|
||||
g = list(group)
|
||||
n = len(g)
|
||||
ah = sum(r["cache_hit_rate"] for r in g) / n
|
||||
ap50 = sum(r["p50_latency_us"] for r in g) / n
|
||||
ap99 = sum(r["p99_latency_us"] for r in g) / n
|
||||
abw = sum(r["memory_bandwidth_mbs"] for r in g) / n
|
||||
al = sum(r["locality_preservation"] for r in g) / n
|
||||
print(f"{hf:<10s} {tp:<20s} {ah*100:>8.2f}% {ap50:>10.2f} {ap99:>10.2f} "
|
||||
f"{abw:>12.1f} {al:>8.3f}")
|
||||
print("=" * 90)
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
# 7. MAIN
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Hash Function Benchmark: Hilbert vs Morton vs xxHash")
|
||||
print("=" * 90)
|
||||
results = run_benchmark()
|
||||
print_summary(results)
|
||||
write_outputs(results)
|
||||
print("\nDone.")
|
||||
241
shared-data/artifacts/hash_benchmark.csv
Normal file
241
shared-data/artifacts/hash_benchmark.csv
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
grid_size,trace_size,trace_pattern,hash_function,cache_hit_rate,p50_latency_us,p99_latency_us,memory_bandwidth_mbs,locality_preservation
|
||||
16,1000,sequential,hilbert,0.0,1.82,6.57,6.17,0.716469
|
||||
16,1000,sequential,morton,0.936,0.819,2.19,13.78,0.0
|
||||
16,1000,sequential,xxhash,0.112,0.97,2.9,11.53,0.008407
|
||||
16,1000,random,hilbert,0.112,1.9,4.92,6.03,0.71932
|
||||
16,1000,random,morton,0.936,0.86,1.61,13.25,0.147023
|
||||
16,1000,random,xxhash,0.197,0.75,2.84,12.77,0.150668
|
||||
16,1000,spatial_locality,hilbert,0.147,1.87,5.38,6.2,0.741935
|
||||
16,1000,spatial_locality,morton,0.936,0.85,3.54,11.73,0.167155
|
||||
16,1000,spatial_locality,xxhash,0.221,0.95,2.92,11.67,0.172043
|
||||
16,1000,temporal_locality,hilbert,0.72,1.03,2.34,10.81,0.955639
|
||||
16,1000,temporal_locality,morton,0.937,0.87,2.12,12.26,0.902658
|
||||
16,1000,temporal_locality,xxhash,0.728,0.47,1.54,20.39,0.902658
|
||||
16,10000,sequential,hilbert,0.5904,1.29,2.85,8.09,0.745367
|
||||
16,10000,sequential,morton,0.9936,0.59,1.67,18.06,0.253674
|
||||
16,10000,sequential,xxhash,0.7385,0.979,2.02,11.81,0.115335
|
||||
16,10000,random,hilbert,0.6255,1.77,3.25,6.71,0.762647
|
||||
16,10000,random,morton,0.9936,0.61,1.02,18.64,0.316765
|
||||
16,10000,random,xxhash,0.7517,1.02,2.17,11.28,0.171765
|
||||
16,10000,spatial_locality,hilbert,0.6451,1.3,2.37,8.66,0.781142
|
||||
16,10000,spatial_locality,morton,0.9936,0.62,1.06,18.56,0.32699
|
||||
16,10000,spatial_locality,xxhash,0.7605,0.97,2.01,11.93,0.183391
|
||||
16,10000,temporal_locality,hilbert,0.7878,1.36,2.96,8.09,0.893909
|
||||
16,10000,temporal_locality,morton,0.9936,1.1,1.88,9.77,0.700386
|
||||
16,10000,temporal_locality,xxhash,0.8317,0.92,2.09,12.22,0.625443
|
||||
16,100000,sequential,hilbert,0.95904,1.31,2.54,8.28,0.853893
|
||||
16,100000,sequential,morton,0.99936,0.62,1.45,15.73,0.456905
|
||||
16,100000,sequential,xxhash,0.97385,0.85,2.07,11.99,0.15636
|
||||
16,100000,random,hilbert,0.95904,1.88,3.419,6.22,0.824273
|
||||
16,100000,random,morton,0.99936,0.69,1.54,14.91,0.461757
|
||||
16,100000,random,xxhash,0.97385,0.74,1.53,14.79,0.179836
|
||||
16,100000,spatial_locality,hilbert,0.95904,1.63,3.84,6.46,0.837229
|
||||
16,100000,spatial_locality,morton,0.99936,0.68,1.67,14.77,0.507937
|
||||
16,100000,spatial_locality,xxhash,0.97385,0.96,2.11,11.61,0.223088
|
||||
16,100000,temporal_locality,hilbert,0.95904,1.75,3.339,6.71,0.855542
|
||||
16,100000,temporal_locality,morton,0.99936,0.99,1.97,10.54,0.542715
|
||||
16,100000,temporal_locality,xxhash,0.97385,1.17,2.53,9.03,0.298132
|
||||
16,1000000,sequential,hilbert,0.995904,1.86,3.8,6.0,0.879824
|
||||
16,1000000,sequential,morton,0.999936,0.79,1.78,13.33,0.579542
|
||||
16,1000000,sequential,xxhash,0.997385,1.06,2.26,10.41,0.187637
|
||||
16,1000000,random,hilbert,0.995904,1.85,3.76,6.16,0.896838
|
||||
16,1000000,random,morton,0.999936,0.76,1.81,13.37,0.614369
|
||||
16,1000000,random,xxhash,0.997385,0.82,2.05,12.28,0.200798
|
||||
16,1000000,spatial_locality,hilbert,0.995904,1.78,3.539,6.54,0.885748
|
||||
16,1000000,spatial_locality,morton,0.999936,0.83,1.819,13.06,0.63457
|
||||
16,1000000,spatial_locality,xxhash,0.997385,0.82,2.09,12.3,0.215548
|
||||
16,1000000,temporal_locality,hilbert,0.995904,1.81,3.69,6.35,0.886049
|
||||
16,1000000,temporal_locality,morton,0.999936,0.97,2.01,11.69,0.610102
|
||||
16,1000000,temporal_locality,xxhash,0.997385,0.88,2.24,11.78,0.202341
|
||||
32,1000,sequential,hilbert,0.0,1.44,3.48,7.69,0.646178
|
||||
32,1000,sequential,morton,0.936,0.82,1.89,13.76,0.0
|
||||
32,1000,sequential,xxhash,0.016,0.7,2.21,15.8,0.001033
|
||||
32,1000,random,hilbert,0.013,1.54,3.13,7.55,0.700935
|
||||
32,1000,random,morton,0.575,0.93,2.83,11.36,0.130841
|
||||
32,1000,random,xxhash,0.022,0.69,2.14,15.98,0.130841
|
||||
32,1000,spatial_locality,hilbert,0.048,2.12,3.88,5.56,0.744526
|
||||
32,1000,spatial_locality,morton,0.633,1.06,3.58,10.2,0.175182
|
||||
32,1000,spatial_locality,xxhash,0.059,1.09,2.489,10.5,0.175182
|
||||
32,1000,temporal_locality,hilbert,0.711,1.259,2.81,9.05,0.99699
|
||||
32,1000,temporal_locality,morton,0.778,0.72,1.839,15.16,0.99378
|
||||
32,1000,temporal_locality,xxhash,0.713,0.74,2.42,14.56,0.99378
|
||||
32,10000,sequential,hilbert,0.0,1.53,2.47,7.5,0.697797
|
||||
32,10000,sequential,morton,0.9744,0.84,1.669,13.31,0.172687
|
||||
32,10000,sequential,xxhash,0.0961,1.02,2.22,10.83,0.001762
|
||||
32,10000,random,hilbert,0.0974,1.74,3.8,6.01,0.743056
|
||||
32,10000,random,morton,0.9488,1.04,2.75,9.33,0.326389
|
||||
32,10000,random,xxhash,0.1899,0.89,2.25,11.5,0.155093
|
||||
32,10000,spatial_locality,hilbert,0.1276,2.18,4.29,5.42,0.757447
|
||||
32,10000,spatial_locality,morton,0.9488,1.12,2.46,10.43,0.319149
|
||||
32,10000,spatial_locality,xxhash,0.2114,1.15,2.39,9.78,0.180851
|
||||
32,10000,temporal_locality,hilbert,0.7156,1.48,2.54,7.87,0.977453
|
||||
32,10000,temporal_locality,morton,0.949,0.84,2.0,13.62,0.936203
|
||||
32,10000,temporal_locality,xxhash,0.7293,0.98,2.39,10.82,0.922111
|
||||
32,100000,sequential,hilbert,0.0,2.19,4.46,5.15,0.804455
|
||||
32,100000,sequential,morton,0.99488,0.86,1.73,12.93,0.423267
|
||||
32,100000,sequential,xxhash,0.12266,1.15,2.29,9.74,0.091584
|
||||
32,100000,random,hilbert,0.12061,2.19,4.11,5.41,0.838554
|
||||
32,100000,random,morton,0.99488,1.1,2.52,9.75,0.460241
|
||||
32,100000,random,xxhash,0.23362,1.0,2.23,10.51,0.13494
|
||||
32,100000,spatial_locality,hilbert,0.15836,1.86,4.01,5.76,0.803738
|
||||
32,100000,spatial_locality,morton,0.99488,0.84,2.0,12.94,0.441589
|
||||
32,100000,spatial_locality,xxhash,0.26775,0.94,2.17,11.11,0.168224
|
||||
32,100000,temporal_locality,hilbert,0.73543,2.32,4.15,5.02,0.915879
|
||||
32,100000,temporal_locality,morton,0.99488,0.92,2.15,11.35,0.791115
|
||||
32,100000,temporal_locality,xxhash,0.76812,0.81,1.67,13.64,0.672968
|
||||
32,1000000,sequential,hilbert,0.0,2.06,4.1,5.64,0.868217
|
||||
32,1000000,sequential,morton,0.999488,0.94,2.21,11.38,0.563307
|
||||
32,1000000,sequential,xxhash,0.125165,0.94,2.34,10.56,0.126615
|
||||
32,1000000,random,hilbert,0.124594,2.15,4.18,5.45,0.866972
|
||||
32,1000000,random,morton,0.999488,1.13,2.67,9.49,0.594037
|
||||
32,1000000,random,xxhash,0.24068,1.08,2.29,10.19,0.169725
|
||||
32,1000000,spatial_locality,hilbert,0.160435,2.1,4.11,5.55,0.896806
|
||||
32,1000000,spatial_locality,morton,0.999488,1.01,2.29,10.87,0.601966
|
||||
32,1000000,spatial_locality,xxhash,0.272339,1.07,2.37,10.13,0.159705
|
||||
32,1000000,temporal_locality,hilbert,0.31645,2.26,4.32,5.15,0.861111
|
||||
32,1000000,temporal_locality,morton,0.999488,1.03,2.52,10.0,0.645299
|
||||
32,1000000,temporal_locality,xxhash,0.417041,1.229,2.68,8.87,0.271368
|
||||
64,1000,sequential,hilbert,0.0,2.24,6.719,4.87,0.645312
|
||||
64,1000,sequential,morton,0.936,0.869,2.17,12.78,0.0
|
||||
64,1000,sequential,xxhash,0.0,1.13,3.14,9.72,0.000521
|
||||
64,1000,random,hilbert,0.0,1.82,3.69,5.99,0.666667
|
||||
64,1000,random,morton,0.111,0.97,2.84,11.47,0.0
|
||||
64,1000,random,xxhash,0.001,0.71,2.63,14.14,0.0
|
||||
64,1000,spatial_locality,hilbert,0.025,1.74,3.49,6.56,0.760479
|
||||
64,1000,spatial_locality,morton,0.314,1.33,5.089,8.14,0.155689
|
||||
64,1000,spatial_locality,xxhash,0.028,0.97,5.65,10.27,0.155689
|
||||
64,1000,temporal_locality,hilbert,0.709,2.83,7.79,3.75,1.0
|
||||
64,1000,temporal_locality,morton,0.718,0.96,3.209,11.22,0.999394
|
||||
64,1000,temporal_locality,xxhash,0.709,0.71,2.12,13.81,0.999394
|
||||
64,10000,sequential,hilbert,0.0,2.33,4.5,4.88,0.728457
|
||||
64,10000,sequential,morton,0.936,0.95,1.92,11.9,0.196393
|
||||
64,10000,sequential,xxhash,0.0136,1.1,2.24,10.38,0.0
|
||||
64,10000,random,hilbert,0.013,2.199,5.189,4.77,0.79661
|
||||
64,10000,random,morton,0.6257,1.64,3.22,6.75,0.322034
|
||||
64,10000,random,xxhash,0.0251,0.76,1.49,14.81,0.220339
|
||||
64,10000,spatial_locality,hilbert,0.0366,2.66,4.92,4.13,0.80531
|
||||
64,10000,spatial_locality,morton,0.6721,1.1,3.03,9.37,0.274336
|
||||
64,10000,spatial_locality,xxhash,0.0501,0.84,2.06,12.02,0.150442
|
||||
64,10000,temporal_locality,hilbert,0.7042,2.46,4.459,4.63,0.996948
|
||||
64,10000,temporal_locality,morton,0.7894,0.9,2.14,12.41,0.989734
|
||||
64,10000,temporal_locality,xxhash,0.7065,0.69,1.53,16.0,0.989456
|
||||
64,100000,sequential,hilbert,0.0,2.45,4.47,4.57,0.794643
|
||||
64,100000,sequential,morton,0.97952,1.07,2.43,10.49,0.348214
|
||||
64,100000,sequential,xxhash,0.01483,1.15,2.36,9.74,0.0
|
||||
64,100000,random,hilbert,0.01491,2.59,5.039,4.37,0.754717
|
||||
64,100000,random,morton,0.95904,1.12,2.789,8.98,0.528302
|
||||
64,100000,random,xxhash,0.03015,0.89,2.17,11.2,0.245283
|
||||
64,100000,spatial_locality,hilbert,0.04087,2.38,4.65,4.76,0.840909
|
||||
64,100000,spatial_locality,morton,0.95904,1.33,2.74,8.82,0.454545
|
||||
64,100000,spatial_locality,xxhash,0.05548,1.14,2.29,9.89,0.068182
|
||||
64,100000,temporal_locality,hilbert,0.70388,2.27,4.59,4.92,0.980226
|
||||
64,100000,temporal_locality,morton,0.95908,1.28,2.86,8.76,0.94774
|
||||
64,100000,temporal_locality,xxhash,0.70837,1.03,2.26,10.76,0.927966
|
||||
64,1000000,sequential,hilbert,0.0,2.37,4.71,4.83,0.87037
|
||||
64,1000000,sequential,morton,0.995904,0.84,2.37,11.73,0.518519
|
||||
64,1000000,sequential,xxhash,0.015167,0.85,2.21,11.45,0.148148
|
||||
64,1000000,random,hilbert,0.015705,2.51,4.68,4.69,0.87931
|
||||
64,1000000,random,morton,0.995904,1.3,3.09,8.35,0.637931
|
||||
64,1000000,random,xxhash,0.030879,0.94,2.31,10.46,0.155172
|
||||
64,1000000,spatial_locality,hilbert,0.039309,2.39,4.54,4.91,0.865385
|
||||
64,1000000,spatial_locality,morton,0.995904,1.15,2.89,9.19,0.634615
|
||||
64,1000000,spatial_locality,xxhash,0.054487,0.95,2.369,10.55,0.134615
|
||||
64,1000000,temporal_locality,hilbert,0.220719,2.62,4.92,4.42,0.948276
|
||||
64,1000000,temporal_locality,morton,0.995904,1.54,3.499,7.2,0.853448
|
||||
64,1000000,temporal_locality,xxhash,0.234006,0.979,2.14,10.9,0.646552
|
||||
128,1000,sequential,hilbert,0.0,2.45,4.84,4.71,0.65397
|
||||
128,1000,sequential,morton,0.936,0.57,1.12,19.84,0.0
|
||||
128,1000,sequential,xxhash,0.0,0.68,1.71,16.06,0.0
|
||||
128,1000,random,hilbert,0.0,2.04,3.74,5.72,1.0
|
||||
128,1000,random,morton,0.106,0.98,2.7,11.49,1.0
|
||||
128,1000,random,xxhash,0.001,0.69,2.07,15.98,1.0
|
||||
128,1000,spatial_locality,hilbert,0.018,1.96,3.939,5.47,0.725664
|
||||
128,1000,spatial_locality,morton,0.276,1.29,3.66,8.78,0.159292
|
||||
128,1000,spatial_locality,xxhash,0.02,0.69,2.04,16.08,0.159292
|
||||
128,1000,temporal_locality,hilbert,0.709,1.69,2.87,6.79,1.0
|
||||
128,1000,temporal_locality,morton,0.721,0.73,1.739,14.71,1.0
|
||||
128,1000,temporal_locality,xxhash,0.709,0.5,1.28,20.96,1.0
|
||||
128,10000,sequential,hilbert,0.0,1.88,2.9,6.19,0.668831
|
||||
128,10000,sequential,morton,0.9744,0.86,1.61,13.47,0.254545
|
||||
128,10000,sequential,xxhash,0.0014,1.22,2.23,9.27,0.0
|
||||
128,10000,random,hilbert,0.0011,2.13,4.28,4.92,0.714286
|
||||
128,10000,random,morton,0.6233,1.01,2.17,11.48,0.214286
|
||||
128,10000,random,xxhash,0.0032,0.75,1.549,14.77,0.071429
|
||||
128,10000,spatial_locality,hilbert,0.0201,1.99,4.59,5.15,0.693878
|
||||
128,10000,spatial_locality,morton,0.651,1.01,2.19,11.31,0.244898
|
||||
128,10000,spatial_locality,xxhash,0.0214,0.99,2.219,10.78,0.122449
|
||||
128,10000,temporal_locality,hilbert,0.7032,2.67,4.18,4.39,1.0
|
||||
128,10000,temporal_locality,morton,0.7872,1.49,3.4,7.39,1.0
|
||||
128,10000,temporal_locality,xxhash,0.7036,0.62,1.32,18.34,0.999439
|
||||
128,100000,sequential,hilbert,0.0,2.66,5.0,4.33,0.756303
|
||||
128,100000,sequential,morton,0.98976,0.67,1.63,15.25,0.394958
|
||||
128,100000,sequential,xxhash,0.00198,0.8,1.55,13.78,0.0
|
||||
128,100000,random,hilbert,0.00187,2.62,4.41,4.58,1.0
|
||||
128,100000,random,morton,0.95904,1.439,3.13,7.7,0.571429
|
||||
128,100000,random,xxhash,0.00373,1.14,2.21,9.95,0.142857
|
||||
128,100000,spatial_locality,hilbert,0.02221,2.74,4.63,4.17,0.777778
|
||||
128,100000,spatial_locality,morton,0.95904,1.079,2.44,10.15,0.222222
|
||||
128,100000,spatial_locality,xxhash,0.02414,0.91,2.08,11.47,0.111111
|
||||
128,100000,temporal_locality,hilbert,0.70039,2.71,4.67,4.43,0.995434
|
||||
128,100000,temporal_locality,morton,0.95905,1.35,2.87,8.52,0.99239
|
||||
128,100000,temporal_locality,xxhash,0.70087,0.88,2.2,11.93,0.990868
|
||||
128,1000000,sequential,hilbert,0.0,2.5,4.61,4.8,0.875
|
||||
128,1000000,sequential,morton,0.995904,1.02,2.56,10.46,0.5
|
||||
128,1000000,sequential,xxhash,0.001913,0.97,2.24,10.71,0.0
|
||||
128,1000000,random,hilbert,0.00197,2.95,5.77,3.76,0.909091
|
||||
128,1000000,random,morton,0.995904,1.469,3.339,7.43,0.545455
|
||||
128,1000000,random,xxhash,0.003894,1.1,2.36,9.76,0.090909
|
||||
128,1000000,spatial_locality,hilbert,0.021323,2.859,5.81,3.77,0.8
|
||||
128,1000000,spatial_locality,morton,0.995904,1.55,3.55,6.93,0.4
|
||||
128,1000000,spatial_locality,xxhash,0.023256,1.3,2.73,8.3,0.2
|
||||
128,1000000,temporal_locality,hilbert,0.208938,3.12,5.87,3.6,1.0
|
||||
128,1000000,temporal_locality,morton,0.995904,1.61,3.73,6.87,0.985714
|
||||
128,1000000,temporal_locality,xxhash,0.210727,1.1,2.26,9.96,0.957143
|
||||
256,1000,sequential,hilbert,0.0,2.66,5.74,4.22,0.701149
|
||||
256,1000,sequential,morton,0.936,0.58,1.35,16.8,0.0
|
||||
256,1000,sequential,xxhash,0.0,1.59,4.31,7.23,0.0
|
||||
256,1000,random,hilbert,0.0,3.26,7.559,3.33,1.0
|
||||
256,1000,random,morton,0.102,2.41,5.379,4.72,1.0
|
||||
256,1000,random,xxhash,0.0,1.03,2.99,10.56,1.0
|
||||
256,1000,spatial_locality,hilbert,0.018,2.959,5.999,3.8,0.697917
|
||||
256,1000,spatial_locality,morton,0.236,1.33,3.61,8.54,0.1875
|
||||
256,1000,spatial_locality,xxhash,0.018,0.69,2.03,15.67,0.1875
|
||||
256,1000,temporal_locality,hilbert,0.709,1.98,3.839,5.87,1.0
|
||||
256,1000,temporal_locality,morton,0.718,1.31,5.36,8.3,1.0
|
||||
256,1000,temporal_locality,xxhash,0.709,0.72,2.23,14.47,1.0
|
||||
256,10000,sequential,hilbert,0.0,2.93,6.219,3.65,0.666255
|
||||
256,10000,sequential,morton,0.9808,1.02,1.83,11.7,0.242274
|
||||
256,10000,sequential,xxhash,0.0003,0.97,2.15,10.96,0.0
|
||||
256,10000,random,hilbert,0.0,3.34,6.51,3.46,0.0
|
||||
256,10000,random,morton,0.6236,1.43,3.21,7.79,0.0
|
||||
256,10000,random,xxhash,0.0003,0.96,1.93,11.07,0.0
|
||||
256,10000,spatial_locality,hilbert,0.0159,3.21,7.46,3.33,0.815789
|
||||
256,10000,spatial_locality,morton,0.6412,1.46,3.75,7.39,0.315789
|
||||
256,10000,spatial_locality,xxhash,0.0161,1.22,2.36,9.71,0.131579
|
||||
256,10000,temporal_locality,hilbert,0.7031,3.09,5.84,3.62,1.0
|
||||
256,10000,temporal_locality,morton,0.7884,1.54,3.65,7.08,1.0
|
||||
256,10000,temporal_locality,xxhash,0.7031,0.72,1.61,14.81,1.0
|
||||
256,100000,sequential,hilbert,0.0,2.94,5.81,3.82,0.795699
|
||||
256,100000,sequential,morton,0.99488,1.17,2.15,10.02,0.419355
|
||||
256,100000,sequential,xxhash,0.00024,1.18,2.34,9.45,0.0
|
||||
256,100000,random,hilbert,0.0002,3.42,6.42,3.31,1.0
|
||||
256,100000,random,morton,0.95904,1.45,3.16,7.8,1.0
|
||||
256,100000,random,xxhash,0.00044,1.23,2.44,8.98,1.0
|
||||
256,100000,spatial_locality,hilbert,0.01778,2.959,5.99,3.74,0.8
|
||||
256,100000,spatial_locality,morton,0.95904,1.16,3.06,8.68,0.0
|
||||
256,100000,spatial_locality,xxhash,0.01798,1.38,2.75,7.96,0.0
|
||||
256,100000,temporal_locality,hilbert,0.69993,3.65,7.26,2.95,1.0
|
||||
256,100000,temporal_locality,morton,0.95906,2.17,4.71,5.31,1.0
|
||||
256,100000,temporal_locality,xxhash,0.7,1.43,3.34,6.99,1.0
|
||||
256,1000000,sequential,hilbert,0.0,2.82,5.22,4.12,0.875
|
||||
256,1000000,sequential,morton,0.998976,0.69,1.96,13.78,0.625
|
||||
256,1000000,sequential,xxhash,0.000235,1.23,2.999,8.62,0.0
|
||||
256,1000000,random,hilbert,0.000241,3.41,6.57,3.23,1.0
|
||||
256,1000000,random,morton,0.995904,1.51,3.34,7.32,1.0
|
||||
256,1000000,random,xxhash,0.000453,1.27,2.72,8.53,1.0
|
||||
256,1000000,spatial_locality,hilbert,0.017244,3.05,5.38,3.76,1.0
|
||||
256,1000000,spatial_locality,morton,0.995904,1.36,2.95,8.15,1.0
|
||||
256,1000000,spatial_locality,xxhash,0.017474,1.2,2.249,9.51,1.0
|
||||
256,1000000,temporal_locality,hilbert,0.207492,3.52,7.01,3.15,1.0
|
||||
256,1000000,temporal_locality,morton,0.995904,1.73,3.56,6.44,0.985294
|
||||
256,1000000,temporal_locality,xxhash,0.20766,1.28,2.58,8.67,0.985294
|
||||
|
2678
shared-data/artifacts/hash_benchmark.json
Normal file
2678
shared-data/artifacts/hash_benchmark.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue