// ── State ──
let currentData = null;
let currentGroup = 'All';
let currentDataset = 'combined';
let sortKey = 'cpt';
let sortDir = 'desc';
let searchQuery = '';
const $ = (sel) => document.querySelector(sel);
const $$ = (sel) => document.querySelectorAll(sel);
function formatNumber(n) {
if (n === null || n === undefined) return '--';
return n.toLocaleString();
}
function formatCompact(n) {
if (n === null || n === undefined) return '--';
if (n >= 1e6) return (n / 1e6).toFixed(1) + 'M';
if (n >= 1e3) return (n / 1e3).toFixed(0) + 'K';
return n.toString();
}
function getBackendClass(backend) {
const map = { 'hf': 'backend-hf', 'tiktoken': 'backend-tiktoken', 'google': 'backend-google', 'anthropic': 'backend-anthropic', 'xai': 'backend-xai' };
return map[backend] || 'backend-hf';
}
function getBackendLabel(backend) {
const map = { 'hf': 'HF', 'tiktoken': 'OpenAI', 'google': 'Google', 'anthropic': 'Anthropic', 'xai': 'xAI' };
return map[backend] || backend;
}
// ── Data Loading ──
function flattenData(data) {
const rows = [];
const allDatasets = new Set();
const datasetGroups = data.dataset_groups || {};
for (const [modelId, model] of Object.entries(data.models || {})) {
for (const [dsName, ds] of Object.entries(model.datasets || {})) {
allDatasets.add(dsName);
rows.push({
model_id: modelId,
model_name: model.model_name || modelId.split('/').pop(),
release_date: model.release_date || '--',
vocab_size: model.vocab_size,
backend: inferBackend(modelId),
dataset: dsName,
group: datasetGroups[dsName] || 'Other',
total_chars: ds.total_chars || 0,
total_tokens: ds.total_tokens || 0,
chars_per_token: ds.chars_per_token || 0,
per_million_output_token_price: model.per_million_output_token_price,
throughput: model.throughput,
});
}
}
const groups = [...new Set(Object.values(datasetGroups))].sort();
return {
rows,
datasets: Array.from(allDatasets).sort(),
groups,
datasetGroups,
timestamp: data.timestamp || ''
};
}
function inferBackend(modelId) {
if (modelId.startsWith('gpt-') || modelId.startsWith('text-embedding')) return 'tiktoken';
if (modelId.startsWith('gemini-')) return 'google';
if (modelId.startsWith('claude-')) return 'anthropic';
if (modelId.startsWith('grok-')) return 'xai';
return 'hf';
}
async function loadData() {
try {
const res = await fetch('data.json');
if (!res.ok) throw new Error('data.json not found');
const data = await res.json();
if (!data.models) throw new Error('invalid format');
currentData = flattenData(data);
renderGroupTabs();
renderDatasetTabs();
renderStats();
renderTable();
renderChart();
$('#timestamp').textContent = currentData.timestamp ? 'run: ' + currentData.timestamp : '';
} catch (e) {
$('#tableBody').innerHTML = `
oops!could not load data.json — ${e.message} |
`;
$('#chartContainer').innerHTML = 'no data.json found
';
}
}
// ── Group Tabs ──
function renderGroupTabs() {
const tabs = $('#groupTabs');
tabs.innerHTML = '';
const groups = ['All', ...currentData.groups];
for (const g of groups) {
const btn = document.createElement('button');
btn.className = 'tab-btn group-tab' + (currentGroup === g ? ' active' : '');
btn.textContent = g;
btn.onclick = () => {
currentGroup = g;
currentDataset = 'combined';
if (g === 'All') {
$('#datasetBar').style.display = 'none';
} else {
$('#datasetBar').style.display = 'flex';
}
renderGroupTabs();
renderDatasetTabs();
renderStats();
renderTable();
renderChart();
};
tabs.appendChild(btn);
}
}
// ── Dataset Tabs ──
function renderDatasetTabs() {
const tabs = $('#datasetTabs');
tabs.innerHTML = '';
if (currentGroup === 'All') return;
const combinedBtn = document.createElement('button');
combinedBtn.className = 'tab-btn' + (currentDataset === 'combined' ? ' active' : '');
combinedBtn.textContent = 'combined';
combinedBtn.onclick = () => { currentDataset = 'combined'; renderDatasetTabs(); renderStats(); renderTable(); renderChart(); };
tabs.appendChild(combinedBtn);
const dsInGroup = currentData.datasets.filter(ds => currentData.datasetGroups[ds] === currentGroup);
for (const ds of dsInGroup) {
const btn = document.createElement('button');
btn.className = 'tab-btn' + (currentDataset === ds ? ' active' : '');
btn.textContent = ds;
btn.onclick = () => { currentDataset = ds; renderDatasetTabs(); renderStats(); renderTable(); renderChart(); };
tabs.appendChild(btn);
}
}
// ── Stats ──
function renderStats() {
const rows = getFilteredRows();
const models = new Set(rows.map(r => r.model_id));
let bestName = '—';
let totalChars = 0;
if (rows.length) {
const sorted = [...rows].sort((a, b) => b.chars_per_token - a.chars_per_token);
bestName = sorted[0].model_name;
totalChars = sorted[0].total_chars;
}
$('#statModels').textContent = models.size;
$('#statChars').textContent = formatCompact(totalChars);
$('#statBest').textContent = bestName.length > 14 ? bestName.slice(0, 12) + '..' : bestName;
}
// ── Filter & Sort ──
function getFilteredRows() {
let rows;
if (currentGroup === 'All' || currentDataset === 'combined') {
const targetDatasets = currentGroup === 'All'
? currentData.datasets
: currentData.datasets.filter(ds => currentData.datasetGroups[ds] === currentGroup);
const modelIds = [...new Set(currentData.rows.map(r => r.model_id))];
rows = [];
for (const mid of modelIds) {
const mrows = currentData.rows.filter(r => r.model_id === mid && targetDatasets.includes(r.dataset));
if (!mrows.length) continue;
const total_chars = mrows.reduce((s, r) => s + r.total_chars, 0);
const total_tokens = mrows.reduce((s, r) => s + r.total_tokens, 0);
const cpts = mrows.map(r => r.total_tokens > 0 ? r.total_chars / r.total_tokens : 0);
const macroCpt = cpts.length > 0 ? cpts.reduce((a, b) => a + b, 0) / cpts.length : 0;
rows.push({
model_id: mid,
model_name: mrows[0].model_name,
release_date: mrows[0].release_date,
vocab_size: mrows[0].vocab_size,
backend: mrows[0].backend,
total_chars,
total_tokens,
chars_per_token: macroCpt,
per_million_output_token_price: mrows[0].per_million_output_token_price,
throughput: mrows[0].throughput,
});
}
} else {
rows = currentData.rows.filter(r => r.dataset === currentDataset).map(r => ({ ...r }));
}
if (searchQuery) {
const q = searchQuery.toLowerCase();
rows = rows.filter(r => r.model_name.toLowerCase().includes(q) || r.model_id.toLowerCase().includes(q));
}
// Compute adjusted values: adjusted = raw * C/T for the current view
for (const r of rows) {
const cpt = r.chars_per_token || 0;
if (r.per_million_output_token_price != null && r.per_million_output_token_price !== undefined) {
r.price_adj = cpt ? r.per_million_output_token_price / cpt : null;
} else {
r.price_adj = null;
}
if (r.throughput != null && r.throughput !== undefined) {
r.throughput_adj = r.throughput * cpt;
} else {
r.throughput_adj = null;
}
}
if (rows.length) {
const maxCPT = Math.max(...rows.map(r => r.chars_per_token));
for (const r of rows) {
// "% more tokens than the best tokenizer for identical text" — matches
// analyze_benchmark.py's compute_pct_more_tokens(): (best/mine - 1) * 100.
// NOT (best-mine)/best — that's a different, smaller number that understates
// the gap for anything far from the best (e.g. reads ~41% where this reads ~69%).
r.pct_more = r.chars_per_token > 0 ? ((maxCPT / r.chars_per_token) - 1) * 100 : 0;
}
}
return rows;
}
function sortRows(rows) {
const keyMap = {
'rank': 'chars_per_token', 'model': 'model_name', 'backend': 'backend',
'date': 'release_date', 'vocab': 'vocab_size', 'tokens': 'total_tokens',
'cpt': 'chars_per_token',
'price': 'per_million_output_token_price', 'price_adj': 'price_adj',
'throughput': 'throughput', 'throughput_adj': 'throughput_adj', 'tax': 'pct_more'
};
const key = keyMap[sortKey] || sortKey;
const dir = sortDir === 'asc' ? 1 : -1;
return [...rows].sort((a, b) => {
let va = a[key];
let vb = b[key];
if (typeof va === 'string') va = va.toLowerCase();
if (typeof vb === 'string') vb = vb.toLowerCase();
if (va === null || va === undefined) va = -Infinity;
if (vb === null || vb === undefined) vb = -Infinity;
if (va < vb) return -1 * dir;
if (va > vb) return 1 * dir;
return 0;
});
}
// ── Table ──
function renderTable() {
const tbody = $('#tableBody');
let rows = getFilteredRows();
if (rows.length === 0) {
tbody.innerHTML = `no resultstry a different search or dataset |
`;
return;
}
rows = sortRows(rows);
const ranked = rows.map((r, i) => ({ ...r, rank: i + 1 }));
const html = ranked.map(r => {
const rankClass = r.rank === 1 ? 'rank-1' : r.rank === 2 ? 'rank-2' : r.rank === 3 ? 'rank-3' : 'rank-other';
const vocab = (r.vocab_size !== null && r.vocab_size !== undefined) ? formatCompact(r.vocab_size) : '--';
const backendClass = getBackendClass(r.backend);
const backendLabel = getBackendLabel(r.backend);
// Price: '--' if null/undefined
const priceVal = (r.per_million_output_token_price != null && r.per_million_output_token_price !== undefined)
? r.per_million_output_token_price.toFixed(2)
: '--';
// Price Adjusted: '--' if null/undefined
const priceAdjVal = (r.price_adj != null && r.price_adj !== undefined)
? r.price_adj.toFixed(2)
: '--';
// Throughput: '--' if null/undefined
const tputVal = (r.throughput != null && r.throughput !== undefined)
? formatCompact(r.throughput)
: '--';
// Throughput Adjusted: Rounded to 0 decimals, '--' if null/undefined
const tputAdjVal = (r.throughput_adj != null && r.throughput_adj !== undefined)
? Math.round(r.throughput_adj).toLocaleString()
: '--';
// Tokenizer Tax: extra tokens vs the most efficient tokenizer in this view.
// 0 means this row IS the most efficient tokenizer — shown as a dash, not "+0.0%".
const taxVal = (r.pct_more != null && r.pct_more > 0)
? '+' + r.pct_more.toFixed(1) + '%'
: '—';
return `
| ${r.rank} |
${r.model_name}
${r.model_id}
|
${backendLabel} |
${vocab} |
${formatCompact(r.total_tokens)} |
${r.chars_per_token.toFixed(2)} |
${priceVal} |
${priceAdjVal} |
${tputVal} |
${tputAdjVal} |
${taxVal} |
`;
}).join('');
tbody.innerHTML = html;
}
// ── Hand-drawn Chart ──
function renderChart() {
const container = $('#chartContainer');
let rows = getFilteredRows();
if (rows.length === 0) {
container.innerHTML = 'no data to sketch
';
return;
}
rows = sortRows(rows);
const displayRows = rows;
const maxCPT = Math.max(...displayRows.map(r => r.chars_per_token)) || 1;
const barHeight = 34;
const barGap = 14;
const labelW = 170;
const chartW = 720;
const chartH = displayRows.length * (barHeight + barGap) + 70;
const barMaxW = chartW - labelW - 90;
const colors = ['#2a9d8f', '#58a6ff', '#e76f51', '#e9c46a', '#8ab17d', '#f4a261', '#2a9d8f', '#58a6ff', '#e76f51', '#e9c46a'];
let svg = `';
container.innerHTML = svg;
const viewLabel = currentGroup === 'All' ? 'All Datasets' :
currentDataset === 'combined' ? currentGroup : currentDataset;
$('#chartTitle').textContent = `Efficiency Sketch — ${viewLabel}`;
}
// ── Event Listeners ──
$('#searchInput').addEventListener('input', (e) => {
searchQuery = e.target.value;
renderTable();
renderChart();
});
$$('.leaderboard th[data-sort]').forEach(th => {
th.addEventListener('click', () => {
const key = th.dataset.sort;
if (sortKey === key) {
sortDir = sortDir === 'asc' ? 'desc' : 'asc';
} else {
sortKey = key;
sortDir = key === 'model' || key === 'date' ? 'asc' : 'desc';
}
$$('.leaderboard th').forEach(t => t.classList.remove('asc', 'desc'));
th.classList.add(sortDir);
renderTable();
renderChart();
});
});
// ── Init ──
loadData();