Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5f950ee
docs: upgrade dry_run from naive paper mode to realistic maker execut…
Milerius Apr 6, 2026
2242441
feat(fixed): add parse_decimal_bytes for zero-alloc hot-path price pa…
Milerius Apr 7, 2026
6778896
bench(fixed): add decimal parse benchmarks with contenders
Milerius Apr 7, 2026
de477b0
refactor(transport): change callback from &str to &mut [u8]
Milerius Apr 7, 2026
2353896
feat(binance): scaffold mantis-binance crate with bookTicker schema
Milerius Apr 7, 2026
98aa60b
feat(binance): implement BinanceDecoder for bookTicker -> TopOfBook
Milerius Apr 7, 2026
e4a473b
feat(polymarket): scaffold mantis-polymarket crate with market WS schema
Milerius Apr 7, 2026
401b3f0
feat(polymarket): implement PolymarketMarketDecoder for book/trade/pr…
Milerius Apr 7, 2026
901d58e
bench: add venue decoder benchmarks for Binance and Polymarket
Milerius Apr 7, 2026
68d65d0
style: fix formatting in decode benchmark
Milerius Apr 7, 2026
f837f00
feat(bench): add standalone SPSC benchmark with cycle-accurate stats …
Milerius Apr 7, 2026
37b8138
bench: replace single-thread SPSC benchmarks with two-thread cross-co…
Milerius Apr 7, 2026
991982e
chore: remove tracked docs/superpowers files (gitignored)
Milerius Apr 7, 2026
665f661
fix: resolve CI failures — yanked fastrand, Display for [u8], doc link
Milerius Apr 7, 2026
49d8aed
style: format live_feeds.rs
Milerius Apr 7, 2026
5d918e6
fix(transport): switch rustls from ring to aws-lc-rs backend
Milerius Apr 7, 2026
f648b4a
fix(ci): remove SPSC references from bench report scripts
Milerius Apr 7, 2026
9ca2927
test(binance,polymarket): add coverage tests for decoder error paths
Milerius Apr 7, 2026
4de2cea
style: fix formatting in polymarket decoder tests
Milerius Apr 7, 2026
23500a2
fix: address CodeRabbit review findings
Milerius Apr 7, 2026
11282f1
fix: address remaining CodeRabbit review findings
Milerius Apr 7, 2026
1fab443
fix(bench): use libc sched_setaffinity instead of core_affinity
Milerius Apr 7, 2026
b1192c4
fix(bench): use sched_setaffinity in C++ harness for isolcpus support
Milerius Apr 7, 2026
7d65ef9
fix(bench): rewrite harness to match HFT University protocol
Milerius Apr 7, 2026
b0934f4
bench: add raw HFT University protocol benchmark (zero overhead)
Milerius Apr 7, 2026
1cc2e47
fix(bench): use split handles in raw bench to avoid aliasing UB
Milerius Apr 7, 2026
493a3fb
bench: zero-overhead raw ring for HFT University protocol
Milerius Apr 7, 2026
c8cb074
bench: optimize RawRing — 64B padding, colocated fields, LTO, branch …
Milerius Apr 7, 2026
854ae89
perf(queue): zero-overhead optimizations — colocated cache lines, boo…
Milerius Apr 7, 2026
a765d86
perf(queue): add push_shared/pop_shared &self API, bench all Rust var…
Milerius Apr 7, 2026
c7f2eba
perf(queue): add SpscRingFast (BranchWrap) + inline(always) on Storage
Milerius Apr 7, 2026
14e3d1c
chore: clean up benchmarks, fix CI clippy, add RESULTS.md
Milerius Apr 7, 2026
4812965
docs: update README with real cross-core benchmark numbers
Milerius Apr 7, 2026
239f6fd
docs: restore emoji highlights in README
Milerius Apr 7, 2026
70f3373
docs: add Optiver/LMAX inspiration note
Milerius Apr 7, 2026
958fe65
feat(bench): add hw counters to Rust bench + raw mode with drogalis t…
Milerius Apr 7, 2026
c806906
bench: add standalone RawRing (zero generics/traits) for baseline com…
Milerius Apr 7, 2026
1c472ad
perf(bench): add local index shadows + fix rdtsc asm in standalone ring
Milerius Apr 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 7 additions & 225 deletions .github/scripts/bench-report.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,216 +5,12 @@ set -euo pipefail
# Usage: bench-report.sh <linux-json> <macos-json>
# Outputs markdown to stdout.

linux_json="${1:?usage: bench-report.sh <linux-spsc> <macos-spsc> [<linux-seqlock> <macos-seqlock>] [<linux-fixed> <macos-fixed>] [<linux-market-state> <macos-market-state>]}"
macos_json="${2:?usage: bench-report.sh <linux-spsc> <macos-spsc> [<linux-seqlock> <macos-seqlock>] [<linux-fixed> <macos-fixed>] [<linux-market-state> <macos-market-state>]}"
linux_seqlock="${3:-}"
macos_seqlock="${4:-}"
linux_fixed="${5:-}"
macos_fixed="${6:-}"
linux_market_state="${7:-}"
macos_market_state="${8:-}"

# Normalize workload names into (impl, pattern, element) and extract metrics.
# Output: JSON array of {impl, pattern, element, ns_per_op, ...}
normalize='
[.results[] | {
workload,
impl: (
if .workload | startswith("spsc/inline/") then "mantis/inline"
elif .workload | startswith("copy/") then "mantis/copy"
elif .workload | startswith("general/") then "mantis/general"
elif .workload | startswith("spsc/rtrb/") then "rtrb"
elif .workload | startswith("spsc/crossbeam/") then "crossbeam"
elif .workload | startswith("spsc/rigtorp/") then "rigtorp-cpp"
elif .workload | startswith("spsc/drogalis/") then "drogalis-cpp"
else "other"
end
),
pattern: (
if (.workload | test("single_item/|single/")) then "single"
elif (.workload | test("burst_100/|burst/100/")) then "burst_100"
elif (.workload | test("burst_1000/|burst/1000/")) then "burst_1000"
elif (.workload | test("batch/100/")) then "batch_100"
elif (.workload | test("batch/1000/")) then "batch_1000"
elif (.workload | test("full_drain/")) then "full_drain"
else "other"
end
),
element: (.workload | split("/") | last),
ns_per_op: (.ns_per_op | . * 100 | round / 100),
cycles: (.cycles_per_op // null | if . == null then null elif . < 0.1 then 0 else (. * 10 | round / 10) end),
insns: (.instructions_per_op // null | if . == null then null else round end),
bmiss: (.branch_misses_per_op // null | if . == null then null elif . < 0.1 then 0 else (. * 10 | round / 10) end)
}]
'

# Build a comparison table for a given pattern.
# Args: $1=json_file $2=pattern $3=title
render_comparison() {
local json="$1" pattern="$2" title="$3"
local data impls elements

data=$(jq -r --arg p "$pattern" "$normalize | map(select(.pattern == \$p))" "$json")
elements=$(echo "$data" | jq -r '[.[].element] | unique | .[]')
impls=$(echo "$data" | jq -r '[.[].impl] | unique | .[]')

# Skip if no data for this pattern
if [ -z "$elements" ]; then
return
fi

# Build header
local header="| Element |"
local separator="|:--------|"
for impl in $impls; do
header="$header $impl |"
separator="$separator------:|"
done

echo "#### $title"
echo ""
echo "$header"
echo "$separator"

# Build rows
for elem in $elements; do
local row="| \`$elem\` |"
# Find the best (lowest) ns/op for this element
local best
best=$(echo "$data" | jq -r --arg e "$elem" \
'[.[] | select(.element == $e) | .ns_per_op] | min')

for impl in $impls; do
local cell
cell=$(echo "$data" | jq -r --arg i "$impl" --arg e "$elem" \
'.[] | select(.impl == $i and .element == $e) | .ns_per_op // empty' 2>/dev/null)
if [ -z "$cell" ]; then
row="$row - |"
else
# Bold the best value with trophy emoji
if [ "$cell" = "$best" ]; then
row="$row **${cell}** 🏆 |"
else
row="$row $cell |"
fi
fi
done
echo "$row"
done
echo ""
}

# Build an insns/op comparison table for a given pattern.
render_insns_comparison() {
local json="$1" pattern="$2" title="$3"
local data impls elements has_any

data=$(jq -r --arg p "$pattern" "$normalize | map(select(.pattern == \$p))" "$json")
elements=$(echo "$data" | jq -r '[.[].element] | unique | .[]')
impls=$(echo "$data" | jq -r '[.[].impl] | unique | .[]')

# Check if any insns data exists
has_any=$(echo "$data" | jq -r '[.[].insns | select(. != null)] | length')
if [ "$has_any" = "0" ] || [ -z "$elements" ]; then
return
fi

local header="| Element |"
local separator="|:--------|"
for impl in $impls; do
header="$header $impl |"
separator="$separator------:|"
done

echo "#### $title"
echo ""
echo "$header"
echo "$separator"

for elem in $elements; do
local row="| \`$elem\` |"
local best
best=$(echo "$data" | jq -r --arg e "$elem" \
'[.[] | select(.element == $e) | .insns | select(. != null)] | min // empty')

for impl in $impls; do
local cell
cell=$(echo "$data" | jq -r --arg i "$impl" --arg e "$elem" \
'.[] | select(.impl == $i and .element == $e) | .insns // empty' 2>/dev/null)
if [ -z "$cell" ] || [ "$cell" = "null" ]; then
row="$row - |"
elif [ -n "$best" ] && [ "$cell" = "$best" ]; then
row="$row **${cell}** 🏆 |"
else
row="$row $cell |"
fi
done
echo "$row"
done
echo ""
}

# Render full detailed table in a collapsible section.
render_full_table() {
local json="$1"

echo "| Workload | ns/op | p50 | p99 | cycles | insns | bmiss | l1d | llc |"
echo "|:---------|------:|----:|----:|-------:|------:|------:|----:|----:|"

jq -r '.results[] |
[
.workload,
(.ns_per_op | . * 100 | round / 100 | tostring),
(.p50_ns | . * 10 | round / 10 | tostring),
(.p99_ns | . * 10 | round / 10 | tostring),
(.cycles_per_op // null | if . == null then "-" elif . < 0.1 then "<0.1" else (. * 10 | round / 10 | tostring) end),
(.instructions_per_op // null | if . == null then "-" else (. | round | tostring) end),
(.branch_misses_per_op // null | if . == null then "-" elif . < 0.1 then "<0.1" else (. * 10 | round / 10 | tostring) end),
(.l1_misses_per_op // null | if . == null then "-" elif . == 0 then "0" else (. * 10 | round / 10 | tostring) end),
(.llc_misses_per_op // null | if . == null then "-" elif . == 0 then "0" else (. * 10 | round / 10 | tostring) end)
] | "| " + join(" | ") + " |"
' "$json"
}

# Render one platform section.
render_platform() {
local json="$1" label="$2"
local cpu arch compiler

if [ ! -f "$json" ]; then
echo "*${label} benchmark results not available.*"
echo ""
return
fi

cpu=$(jq -r '.cpu' "$json")
arch=$(jq -r '.arch' "$json")
compiler=$(jq -r '.compiler' "$json")

echo "**CPU:** \`${cpu}\` | **Arch:** \`${arch}\` | **Compiler:** \`${compiler}\`"
echo ""

echo "##### Latency (ns/op, lower is better)"
echo ""
render_comparison "$json" "single" "Single Push+Pop"
render_comparison "$json" "burst_100" "Burst 100"
render_comparison "$json" "burst_1000" "Burst 1000"
render_comparison "$json" "batch_100" "Batch 100"
render_comparison "$json" "batch_1000" "Batch 1000"
render_comparison "$json" "full_drain" "Full Drain"

echo "##### Instructions per Op (lower is better)"
echo ""
render_insns_comparison "$json" "single" "Single Push+Pop"
render_insns_comparison "$json" "burst_100" "Burst 100"

echo "<details>"
echo "<summary>Full results (all fields)</summary>"
echo ""
render_full_table "$json"
echo ""
echo "</details>"
}
linux_seqlock="${1:?usage: bench-report.sh <linux-seqlock> <macos-seqlock> [<linux-fixed> <macos-fixed>] [<linux-market-state> <macos-market-state>]}"
macos_seqlock="${2:?}"
linux_fixed="${3:-}"
macos_fixed="${4:-}"
linux_market_state="${5:-}"
macos_market_state="${6:-}"

# Render grouped benchmark results from Criterion JSON report.
# Args: $1=json_file $2=label $3=suite_name (e.g. "fixed-point", "seqlock")
Expand Down Expand Up @@ -266,22 +62,8 @@ cat <<HEADER

HEADER

echo "<details open>"
echo "<summary><strong>Linux</strong></summary>"
echo ""
render_platform "$linux_json" "Linux"
echo "</details>"
echo ""

echo "<details open>"
echo "<summary><strong>macOS</strong></summary>"
echo ""
render_platform "$macos_json" "macOS"
echo "</details>"

# Seqlock benchmarks (optional)
# Seqlock benchmarks
if [ -n "$linux_seqlock" ] || [ -n "$macos_seqlock" ]; then
echo ""
echo "### Sequence Lock (mantis-seqlock)"
echo ""

Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/criterion-to-json.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ for est in "${matched_ests[@]}"; do
'. + [{"workload": $w, "ns_per_op": ($ns | . * 100 | round / 100)}]')
done

# Wrap in the same schema as spsc report
# Wrap in the standard bench report schema
cpu="unknown"
arch="unknown"
compiler="unknown"
Expand Down
20 changes: 5 additions & 15 deletions .github/workflows/bench.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,6 @@ jobs:
- name: Allow perf_event_open (Linux)
if: runner.os == 'Linux'
run: sudo sysctl -w kernel.perf_event_paranoid=1
# ── SPSC benchmarks (custom harness, outputs JSON directly) ──
- name: Run SPSC benchmarks
run: cargo +nightly bench --bench spsc --all-features
env:
RUSTFLAGS: "-C target-cpu=native"
- name: Convert SPSC report for CI tracking
run: |
jq '[.results[] | {name: .workload, unit: "ns/op", value: .ns_per_op}]' \
target/bench-report-spsc.json > bench-output-spsc.json

# ── Seqlock benchmarks (Criterion) ──
# IMPORTANT: Each Criterion bench must be converted IMMEDIATELY after running,
# before the next `rm -rf target/criterion`. The criterion-to-json.sh script
Expand Down Expand Up @@ -97,7 +87,7 @@ jobs:
target/bench-report-market_state.json > bench-output-market_state.json
- name: Merge benchmark outputs
run: |
jq -s 'add' bench-output-spsc.json bench-output-seqlock.json bench-output-fixed.json bench-output-market_state.json > bench-output.json
jq -s 'add' bench-output-seqlock.json bench-output-fixed.json bench-output-market_state.json > bench-output.json
- name: Restore Cargo.lock before gh-pages switch
run: git checkout -- Cargo.lock
- name: Store benchmark result
Expand All @@ -117,7 +107,6 @@ jobs:
with:
name: benchmark-results-${{ matrix.os }}
path: |
target/bench-report-spsc.json
target/bench-report-seqlock.json
target/bench-report-fixed.json
target/bench-report-market_state.json
Expand Down Expand Up @@ -149,15 +138,16 @@ jobs:
continue-on-error: true
- name: Generate markdown report
run: |
linux_spsc="results/linux/target/bench-report-spsc.json"
macos_spsc="results/macos/target/bench-report-spsc.json"
linux_seqlock="results/linux/target/bench-report-seqlock.json"
macos_seqlock="results/macos/target/bench-report-seqlock.json"
linux_fixed="results/linux/target/bench-report-fixed.json"
macos_fixed="results/macos/target/bench-report-fixed.json"
linux_market_state="results/linux/target/bench-report-market_state.json"
macos_market_state="results/macos/target/bench-report-market_state.json"
bash .github/scripts/bench-report.sh "$linux_spsc" "$macos_spsc" "$linux_seqlock" "$macos_seqlock" "$linux_fixed" "$macos_fixed" "$linux_market_state" "$macos_market_state" > report.md
bash .github/scripts/bench-report.sh \
"$linux_seqlock" "$macos_seqlock" \
"$linux_fixed" "$macos_fixed" \
"$linux_market_state" "$macos_market_state" > report.md
- name: Post PR comment
uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1
with:
Expand Down
Loading
Loading