Spaces:
Running
Running
Allow zero weights in composite scores and average ranks
Browse filesInclude all 66 non-negative one-decimal triples summing to 1.0, including the three single-metric endpoints. Keep the default 0.4/0.3/0.3 and the existing ranking and missing-measurement rules. Update weight validation and help text.
- README.md +1 -1
- app.js +1 -1
- index.html +3 -3
- ranking.js +4 -4
README.md
CHANGED
|
@@ -38,7 +38,7 @@ Only measurements in the authoritative current project scope are exported. Missi
|
|
| 38 |
- Compression rate versus encoding/decoding cost plots
|
| 39 |
- Dataset-level method details, snapshot provenance, and metric definitions
|
| 40 |
- Searchable 169-dataset catalog grouped into six source categories, with explicit measurement availability and source links
|
| 41 |
-
- Overall composite score and average dataset Rank, with
|
| 42 |
- Searchable Methods documentation and a 30-family operator catalog with 102 implementation-directory entries, references, I/O contracts, examples, and status
|
| 43 |
|
| 44 |
The dataset catalog and measured benchmark scope are separate. All 169 catalog entries are searchable and selectable. Dataset coverage can differ by method and runtime; unavailable combinations show **No published measurements**, remain excluded from rankings, and are never converted to zero-valued results. The default family view selects the best measured compression-rate configuration independently for each measured dataset. Switch to **Exact configuration** to hold a configuration fixed. Runtime results stay separate.
|
|
|
|
| 38 |
- Compression rate versus encoding/decoding cost plots
|
| 39 |
- Dataset-level method details, snapshot provenance, and metric definitions
|
| 40 |
- Searchable 169-dataset catalog grouped into six source categories, with explicit measurement availability and source links
|
| 41 |
+
- Overall composite score and average dataset Rank, with 66 valid non-negative one-decimal weight combinations, including zero weights
|
| 42 |
- Searchable Methods documentation and a 30-family operator catalog with 102 implementation-directory entries, references, I/O contracts, examples, and status
|
| 43 |
|
| 44 |
The dataset catalog and measured benchmark scope are separate. All 169 catalog entries are searchable and selectable. Dataset coverage can differ by method and runtime; unavailable combinations show **No published measurements**, remain excluded from rankings, and are never converted to zero-valued results. The default family view selects the best measured compression-rate configuration independently for each measured dataset. Switch to **Exact configuration** to hold a configuration fixed. Runtime results stay separate.
|
app.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import {WEIGHT_TENTHS,parseWeights,addRankingMetrics} from './ranking.js?v=20261009-
|
| 2 |
const $ = (id) => document.getElementById(id);
|
| 3 |
const escape = (value) => String(value ?? '').replace(/[&<>"']/g, (c) => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
| 4 |
const number = (v) => v != null && Number.isFinite(Number(v)) ? Number(v) : null;
|
|
|
|
| 1 |
+
import {WEIGHT_TENTHS,parseWeights,addRankingMetrics} from './ranking.js?v=20261009-zero-weights-v1';
|
| 2 |
const $ = (id) => document.getElementById(id);
|
| 3 |
const escape = (value) => String(value ?? '').replace(/[&<>"']/g, (c) => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
| 4 |
const number = (v) => v != null && Number.isFinite(Number(v)) ? Number(v) : null;
|
index.html
CHANGED
|
@@ -7,7 +7,7 @@
|
|
| 7 |
<meta name="color-scheme" content="light dark">
|
| 8 |
<title>THULab | Time Series Compression Benchmark</title>
|
| 9 |
<link rel="stylesheet" href="style.css?v=20261009-dbp-integrated-v1">
|
| 10 |
-
<script src="app.js?v=20261009-
|
| 11 |
</head>
|
| 12 |
<body>
|
| 13 |
<a class="skip-link" href="#content">Skip to results</a>
|
|
@@ -65,7 +65,7 @@
|
|
| 65 |
<div class="results-note" id="results-note">Compression rate = compressed bytes / original bytes. Lower rates and lower ns/point are better. Metrics aggregate the numeric columns measured for each method; column coverage may differ.</div>
|
| 66 |
<div id="score-controls" class="score-controls">
|
| 67 |
<label>Score weights · a: rate / b: encode / c: decode<select id="weights" aria-label="Score weights a b c"></select></label>
|
| 68 |
-
<p id="score-note" class="muted" aria-live="polite">
|
| 69 |
</div>
|
| 70 |
<div class="table-settings">
|
| 71 |
<label><input id="complete-only" type="checkbox"> Only methods covering the full selection</label>
|
|
@@ -111,7 +111,7 @@
|
|
| 111 |
<div><dt>Encoding / decoding cost ↓</dt><dd>Nanoseconds per point under each result's recorded measurement contract. Native-float measurements use valid native values; historical imported rows retain their source 8-byte-equivalent point definition. Compare timings within the same runtime and measurement contract.</dd></div>
|
| 112 |
<div><dt>Coverage</dt><dd>Datasets with usable measurements for a method out of the datasets in the selected scope. Missing results are never filled with zero.</dd></div>
|
| 113 |
<div><dt>Composite score ↓</dt><dd>a × average compression rate + b × normalized average encoding time + c × normalized average decoding time. Each time uses min–max over all measured rows in the selected runtime, scope and row mode, before search, family and coverage filters. If all times are equal, their normalized value is zero. All measured inputs must have usable timing metrics.</dd></div>
|
| 114 |
-
<div><dt>Average Rank ↓</dt><dd>Compute the same weighted score within each dataset, normalizing times within that dataset. Rank lower scores first; ties share their average position. Then take the arithmetic mean of the method's available dataset ranks. Weights are
|
| 115 |
</dl>
|
| 116 |
<h3>Reading the rankings</h3>
|
| 117 |
<p>Methods with different coverage are measured on different inputs. Coverage counts datasets, not identical columns or point counts. Use the full-coverage filter and inspect a single dataset's input sizes before drawing a direct comparison. Runtime filters keep Python, C++, and Java measurements separate.</p>
|
|
|
|
| 7 |
<meta name="color-scheme" content="light dark">
|
| 8 |
<title>THULab | Time Series Compression Benchmark</title>
|
| 9 |
<link rel="stylesheet" href="style.css?v=20261009-dbp-integrated-v1">
|
| 10 |
+
<script src="app.js?v=20261009-zero-weights-v1" type="module"></script>
|
| 11 |
</head>
|
| 12 |
<body>
|
| 13 |
<a class="skip-link" href="#content">Skip to results</a>
|
|
|
|
| 65 |
<div class="results-note" id="results-note">Compression rate = compressed bytes / original bytes. Lower rates and lower ns/point are better. Metrics aggregate the numeric columns measured for each method; column coverage may differ.</div>
|
| 66 |
<div id="score-controls" class="score-controls">
|
| 67 |
<label>Score weights · a: rate / b: encode / c: decode<select id="weights" aria-label="Score weights a b c"></select></label>
|
| 68 |
+
<p id="score-note" class="muted" aria-live="polite">Non-negative weights in steps of 0.1, summing to 1.0.</p>
|
| 69 |
</div>
|
| 70 |
<div class="table-settings">
|
| 71 |
<label><input id="complete-only" type="checkbox"> Only methods covering the full selection</label>
|
|
|
|
| 111 |
<div><dt>Encoding / decoding cost ↓</dt><dd>Nanoseconds per point under each result's recorded measurement contract. Native-float measurements use valid native values; historical imported rows retain their source 8-byte-equivalent point definition. Compare timings within the same runtime and measurement contract.</dd></div>
|
| 112 |
<div><dt>Coverage</dt><dd>Datasets with usable measurements for a method out of the datasets in the selected scope. Missing results are never filled with zero.</dd></div>
|
| 113 |
<div><dt>Composite score ↓</dt><dd>a × average compression rate + b × normalized average encoding time + c × normalized average decoding time. Each time uses min–max over all measured rows in the selected runtime, scope and row mode, before search, family and coverage filters. If all times are equal, their normalized value is zero. All measured inputs must have usable timing metrics.</dd></div>
|
| 114 |
+
<div><dt>Average Rank ↓</dt><dd>Compute the same weighted score within each dataset, normalizing times within that dataset. Rank lower scores first; ties share their average position. Then take the arithmetic mean of the method's available dataset ranks. Weights are non-negative tenths summing to 1.0. Missing measurements do not receive ranks.</dd></div>
|
| 115 |
</dl>
|
| 116 |
<h3>Reading the rankings</h3>
|
| 117 |
<p>Methods with different coverage are measured on different inputs. Coverage counts datasets, not identical columns or point counts. Use the full-coverage filter and inspect a single dataset's input sizes before drawing a direct comparison. Runtime filters keep Python, C++, and Java measurements separate.</p>
|
ranking.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
// Ranking references include all measured methods in the selected runtime,
|
| 2 |
// scope and row mode. Search, family and coverage filters only hide rows.
|
| 3 |
export const WEIGHT_TENTHS = [];
|
| 4 |
-
for (let a=
|
| 5 |
|
| 6 |
export function parseWeights(value) {
|
| 7 |
-
const
|
| 8 |
-
if(parts.length!==3||parts.some(n=>!Number.isInteger(n)||n<
|
| 9 |
return parts.map(n=>n/10);
|
| 10 |
}
|
| 11 |
|
|
@@ -29,7 +29,7 @@ function score(row,weights,encodeRange,decodeRange) {
|
|
| 29 |
}
|
| 30 |
|
| 31 |
export function addRankingMetrics(rows,weights) {
|
| 32 |
-
if(weights.length!==3||weights.some(w=>!finite(w)||w<
|
| 33 |
const candidates=rows.filter(r=>valid(r)&&r.source.every(valid));
|
| 34 |
const encodeRange=bounds(candidates,'compression_time'),decodeRange=bounds(candidates,'decompression_time');
|
| 35 |
const byDataset=new Map(),ranks=new Map(),details=new Map();
|
|
|
|
| 1 |
// Ranking references include all measured methods in the selected runtime,
|
| 2 |
// scope and row mode. Search, family and coverage filters only hide rows.
|
| 3 |
export const WEIGHT_TENTHS = [];
|
| 4 |
+
for (let a=0;a<=10;a++) for (let b=0;b<=10-a;b++) WEIGHT_TENTHS.push([a,b,10-a-b]);
|
| 5 |
|
| 6 |
export function parseWeights(value) {
|
| 7 |
+
const tokens=String(value).split(','),parts=tokens.map(Number);
|
| 8 |
+
if(parts.length!==3||tokens.some(t=>t.trim()==='')||parts.some(n=>!Number.isInteger(n)||n<0)||parts.reduce((s,n)=>s+n,0)!==10) throw new Error('Weights must be non-negative tenths summing to 1.0.');
|
| 9 |
return parts.map(n=>n/10);
|
| 10 |
}
|
| 11 |
|
|
|
|
| 29 |
}
|
| 30 |
|
| 31 |
export function addRankingMetrics(rows,weights) {
|
| 32 |
+
if(weights.length!==3||weights.some(w=>!finite(w)||w<0)||Math.abs(weights.reduce((s,w)=>s+w,0)-1)>1e-12)throw new Error('Invalid scoring weights.');
|
| 33 |
const candidates=rows.filter(r=>valid(r)&&r.source.every(valid));
|
| 34 |
const encodeRange=bounds(candidates,'compression_time'),decodeRange=bounds(candidates,'decompression_time');
|
| 35 |
const byDataset=new Map(),ranks=new Map(),details=new Map();
|