Skip to content

Commit c48fd23

Browse files
authored
Merge pull request #495 from MDA2AV/site/grp
group implementations, improve framework card
2 parents 6300f44 + 965b667 commit c48fd23

9 files changed

Lines changed: 431 additions & 81 deletions

scripts/benchmark.sh

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,26 +79,47 @@ rebuild_site_data() {
7979
local site_data="$ROOT_DIR/site/data"
8080
mkdir -p "$site_data"
8181

82-
# Rebuild frameworks.json from individual meta.json files
82+
# Rebuild frameworks.json from individual meta.json files.
83+
# Hybrid shape: the "primary" entry fields (dir/description/repo/type/engine)
84+
# stay at top level for backwards compatibility with all leaderboards.
85+
# Additional entries that share the same display_name go in `variants`
86+
# (read only by the composite popup to show every aggregated variant).
87+
# Primary is chosen as the entry whose dir matches the display_name, or
88+
# the first alphabetically.
8389
local fw_json="$site_data/frameworks.json"
84-
echo '{' > "$fw_json"
85-
local fw_first=true
86-
for fw_dir in "$ROOT_DIR"/frameworks/*/; do
87-
[ -d "$fw_dir" ] || continue
88-
local fw=$(basename "$fw_dir")
89-
local meta="$fw_dir/meta.json"
90-
[ -f "$meta" ] || continue
91-
$fw_first || echo ',' >> "$fw_json"
92-
local dn=$(python3 -c "import json,sys; d=json.load(open(sys.argv[1])); print(d.get('display_name',sys.argv[2]))" "$meta" "$fw")
93-
local desc=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1])).get('description',''))" "$meta")
94-
local repo=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1])).get('repo',''))" "$meta")
95-
local ftype=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1])).get('type','realistic'))" "$meta")
96-
local engine=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1])).get('engine',''))" "$meta")
97-
printf ' "%s": {"dir": "%s", "description": "%s", "repo": "%s", "type": "%s", "engine": "%s"}' "$dn" "$fw" "$desc" "$repo" "$ftype" "$engine" >> "$fw_json"
98-
fw_first=false
99-
done
100-
echo '' >> "$fw_json"
101-
echo '}' >> "$fw_json"
90+
python3 - "$ROOT_DIR" > "$fw_json" <<'PYEOF'
91+
import json, sys, os, glob
92+
root = sys.argv[1]
93+
groups = {}
94+
for meta_path in sorted(glob.glob(os.path.join(root, "frameworks", "*", "meta.json"))):
95+
fw_dir = os.path.basename(os.path.dirname(meta_path))
96+
try:
97+
with open(meta_path) as f:
98+
m = json.load(f)
99+
except Exception:
100+
continue
101+
display = m.get("display_name", fw_dir)
102+
entry = {
103+
"dir": fw_dir,
104+
"description": m.get("description", ""),
105+
"repo": m.get("repo", ""),
106+
"type": m.get("type", "realistic"),
107+
"engine": m.get("engine", ""),
108+
}
109+
groups.setdefault(display, []).append(entry)
110+
111+
out = {}
112+
for display, entries in groups.items():
113+
# Primary = the one whose dir == display_name, else first alphabetical
114+
entries_sorted = sorted(entries, key=lambda e: e["dir"])
115+
primary = next((e for e in entries_sorted if e["dir"] == display), entries_sorted[0])
116+
variants = [e for e in entries_sorted if e["dir"] != primary["dir"]]
117+
obj = dict(primary)
118+
if variants:
119+
obj["variants"] = variants
120+
out[display] = obj
121+
print(json.dumps(out, indent=2))
122+
PYEOF
102123
echo "[updated] site/data/frameworks.json"
103124

104125
for profile_dir in "$RESULTS_DIR"/*/; do

site/data/baseline-h3-256.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

site/data/baseline-h3-512.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

site/data/frameworks.json

Lines changed: 358 additions & 50 deletions
Large diffs are not rendered by default.

site/data/static-h3-256.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

site/data/static-h3-512.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

site/layouts/shortcodes/leaderboard-composite.html

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,24 +1009,46 @@
10091009
if (r.framework === 'genhttp') {
10101010
popupBadges += '<div style="margin-bottom:0.5rem; display:flex; align-items:center; gap:0.5rem;"><span style="font-size:1.5rem; filter:brightness(0.7) sepia(1) saturate(3) hue-rotate(-10deg);">\uD83C\uDFC5</span><span style="font-weight:700; font-size:0.95rem; color:#B45309;">Participation Award</span></div><div style="margin-bottom:0.5rem; font-size:0.8rem; font-style:italic; color:#B45309;">He\'s happy to be here</div>';
10111011
}
1012-
var popupBadgeSection = popupBadges ? '<div style="margin:0.75rem 0; padding:0.75rem; background:rgba(0,0,0,0.02); border-radius:8px; border:1px solid rgba(0,0,0,0.06);">' + popupBadges + '</div>' : '';
1012+
// Awards section collapsed by default (<details>) — was occupying too much vertical space
1013+
var popupBadgeSection = popupBadges
1014+
? '<details class="lb-popup-awards" style="margin:0.75rem 0; padding:0.6rem 0.75rem; background:rgba(0,0,0,0.02); border-radius:8px; border:1px solid rgba(0,0,0,0.06);">'
1015+
+ '<summary style="cursor:pointer; font-weight:600; font-size:0.85rem; color:#475569; user-select:none;">Awards &amp; Badges</summary>'
1016+
+ '<div style="margin-top:0.6rem;">' + popupBadges + '</div>'
1017+
+ '</details>'
1018+
: '';
1019+
1020+
// Build one "variant" section per framework directory sharing this display_name.
1021+
// `fmeta.variants` contains sibling entries; we merge primary + variants into one list.
1022+
var variantsList = [{ dir: fmeta.dir || r.framework, description: fmeta.description || '', repo: fmeta.repo || '' }];
1023+
if (Array.isArray(fmeta.variants)) {
1024+
fmeta.variants.forEach(function(v) {
1025+
variantsList.push({ dir: v.dir, description: v.description || '', repo: v.repo || '' });
1026+
});
1027+
}
1028+
var variantsHtml = variantsList.map(function(v) {
1029+
var header = variantsList.length > 1
1030+
? '<div style="font-size:0.75rem; font-weight:600; color:#64748b; text-transform:uppercase; letter-spacing:0.04em; margin-top:0.5rem;">' + v.dir + '</div>'
1031+
: '';
1032+
var desc = v.description ? '<div class="lb-popup-desc" style="margin-top:0.2rem;">' + v.description + '</div>' : '';
1033+
var repoLink = v.repo ? '<a class="lb-popup-link" href="' + v.repo + '" target="_blank" rel="noreferrer">View source &rarr;</a>' : '';
1034+
var benchLink = '<a class="lb-popup-link" href="https://github.com/MDA2AV/HttpArena/tree/main/frameworks/' + encodeURIComponent(v.dir) + '" target="_blank" rel="noreferrer">Benchmark implementation &rarr;</a>';
1035+
var links = '<div class="lb-popup-links" style="margin-top:0.35rem;">' + repoLink + benchLink + '</div>';
1036+
return header + desc + links;
1037+
}).join('');
10131038

1014-
var repoHtml = fmeta.repo ? '<a class="lb-popup-link" href="' + fmeta.repo + '" target="_blank" rel="noreferrer">View source &rarr;</a>' : '';
1015-
var benchHtml = '<a class="lb-popup-link" href="https://github.com/MDA2AV/HttpArena/tree/main/frameworks/' + encodeURIComponent(r.framework) + '" target="_blank" rel="noreferrer">Benchmark implementation &rarr;</a>';
10161039
var overlay = document.createElement('div');
10171040
overlay.className = 'lb-overlay';
10181041
overlay.innerHTML =
10191042
'<div class="lb-popup">' +
10201043
'<button class="lb-popup-close" aria-label="Close">&times;</button>' +
10211044
'<div class="lb-popup-name">' + r.framework + '</div>' +
10221045
'<div class="lb-popup-lang">' + r.language + '</div>' +
1023-
'<div class="lb-popup-desc">' + (fmeta.description || '') + '</div>' +
1046+
variantsHtml +
10241047
popupBadgeSection +
10251048
'<div class="lb-popup-stats">' +
10261049
'<div><div class="lb-popup-stat-label">Composite Score</div><div class="lb-popup-stat-value" style="font-size:1.5rem; font-weight:700;">' + r.composite.toFixed(1) + '</div></div>' +
10271050
profileDetails +
10281051
'</div>' +
1029-
'<div class="lb-popup-links">' + repoHtml + benchHtml + '</div>' +
10301052
'</div>';
10311053
document.body.appendChild(overlay);
10321054
function close() { overlay.remove(); }

site/layouts/shortcodes/leaderboard-h1-isolated.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,13 +219,16 @@
219219
border-radius: 12px;
220220
padding: 2rem 2.5rem;
221221
max-width: 520px; width: 90vw;
222+
max-height: 85vh; overflow-y: auto;
222223
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.15);
223224
position: relative;
224225
}
225226
.lb-popup-close {
226-
position: absolute; top: 1rem; right: 1.25rem;
227+
position: sticky; top: 0; float: right;
228+
margin: -0.5rem -1rem 0 0;
227229
background: none; border: none; font-size: 1.4rem;
228230
color: #94a3b8; cursor: pointer; line-height: 1;
231+
z-index: 1;
229232
}
230233
.lb-popup-close:hover { color: #334155; }
231234
.lb-popup-name { font-size: 1.4rem; font-weight: 700; margin-bottom: 0.25rem; }

site/layouts/shortcodes/leaderboard-h3.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{{ $profiles := slice
2-
(dict "id" "baseline-h3" "label" "Baseline (HTTP/3)" "conns" (slice 256 512) "desc" "Same workload as the HTTP/1.1 baseline — <code>GET /baseline2</code> with query parameter parsing — but over HTTP/3 (QUIC) with TLS 1.3. Benchmarked with <code>oha</code> using 128 parallel streams per connection. Measures how efficiently a framework handles HTTP/3 over UDP-based QUIC transport. Container pinned to 64 CPU threads (cores 0-31, 64-95). <a href='/docs/test-profiles/h3/baseline-h3/' class='lb-desc-link'>Learn more &rarr;</a>")
3-
(dict "id" "static-h3" "label" "Static Files (HTTP/3)" "conns" (slice 256 512) "desc" "Serves 20 static files of various types and sizes (CSS, JS, HTML, fonts, SVG, WebP, JSON — totaling ~325 KB) over HTTP/3 (QUIC) with TLS 1.3. The load generator (<code>oha</code>) requests all files using 128 parallel streams per connection, simulating a realistic browser page load over QUIC. Container pinned to 64 CPU threads (cores 0-31, 64-95). <a href='/docs/test-profiles/h3/static-h3/' class='lb-desc-link'>Learn more &rarr;</a>")
2+
(dict "id" "baseline-h3" "label" "Baseline (HTTP/3)" "conns" (slice 64) "desc" "Same workload as the HTTP/1.1 baseline — <code>GET /baseline2</code> with query parameter parsing — but over HTTP/3 (QUIC) with TLS 1.3. Benchmarked with <code>h2load-h3</code> using 64 connections × 64 streams × 64 threads. Measures how efficiently a framework handles HTTP/3 over UDP-based QUIC transport. Container pinned to 64 CPU threads (cores 0-31, 64-95). <a href='/docs/test-profiles/h3/baseline-h3/' class='lb-desc-link'>Learn more &rarr;</a>")
3+
(dict "id" "static-h3" "label" "Static Files (HTTP/3)" "conns" (slice 64) "desc" "Serves 20 static files of various types and sizes (CSS, JS, HTML, fonts, SVG, WebP, JSON — totaling ~325 KB) over HTTP/3 (QUIC) with TLS 1.3. Benchmarked with <code>h2load-h3</code> using 64 connections × 64 streams × 64 threads, simulating a realistic browser page load over QUIC. Container pinned to 64 CPU threads (cores 0-31, 64-95). <a href='/docs/test-profiles/h3/static-h3/' class='lb-desc-link'>Learn more &rarr;</a>")
44
}}
55

66
{{/* Build JSON data blob for round switching */}}

0 commit comments

Comments
 (0)