name: benchmark-report
run-name: benchmark-report (${{ inputs.benchmark_variant || 'basic' }}) for ${{ inputs.head_ref || github.ref_name }} @ ${{ inputs.head_sha || github.sha }}
on:
push:
branches:
- master
paths:
- "src/**"
- "benches/**"
- "tools/criterion-export/**"
- "scripts/**"
- "justfile"
- "Cargo.toml"
- "Cargo.lock"
- ".github/workflows/benchmark-report.yml"
- "BENCHMARKING.md"
workflow_dispatch:
inputs:
pr_number:
description: "Pull request number for comment-dispatched benchmark runs"
required: false
type: string
head_sha:
description: "Head commit SHA to benchmark"
required: false
type: string
head_ref:
description: "Head branch name to benchmark"
required: false
type: string
head_repo:
description: "Head repository full name to benchmark"
required: false
type: string
benchmark_variant:
description: "Benchmark suite variant"
required: false
type: choice
default: basic
options:
- basic
- extended
- dist
- leaf
- stems
- construction
concurrency:
group: benchmark-report-${{ inputs.head_ref || github.ref_name }}-${{ inputs.benchmark_variant || 'basic' }}
cancel-in-progress: false
permissions:
contents: write
pull-requests: write
env:
LATEST_STABLE_RUST_VERSION: "TBD"
jobs:
benchmark:
runs-on: [self-hosted, Linux, X64]
outputs:
benchmark_variant: ${{ steps.meta.outputs.benchmark_variant }}
published_variant: ${{ steps.meta.outputs.published_variant }}
ref_name: ${{ steps.meta.outputs.ref_name }}
run_sha: ${{ steps.meta.outputs.run_sha }}
variant_key: ${{ steps.meta.outputs.variant_key }}
site_url_base: ${{ steps.meta.outputs.site_url_base }}
steps:
- uses: actions/checkout@v7
with:
repository: ${{ inputs.head_repo || github.repository }}
ref: ${{ inputs.head_sha || github.sha }}
show-progress: false
- name: Get latest stable Rust version
run: |
echo "LATEST_STABLE_RUST_VERSION=$(gh api /repos/rust-lang/rust/releases --jq ".[0].tag_name")" >> "$GITHUB_ENV"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Cache Toolchain
uses: actions/cache@v6
with:
path: ~/.rustup
key: toolchain-x86-64-${{ env.LATEST_STABLE_RUST_VERSION }}
- name: Install `stable` Toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Install `just`
uses: baptiste0928/cargo-install@v3
with:
crate: just
version: "^1"
- name: Install `cargo-criterion`
uses: baptiste0928/cargo-install@v3
with:
crate: cargo-criterion
version: "^1"
- name: Derive metadata
id: meta
run: |
ref_name="${{ inputs.head_ref || github.ref_name }}"
run_sha="${{ inputs.head_sha || github.sha }}"
benchmark_variant="${{ inputs.benchmark_variant || 'basic' }}"
variant_key=$(python3 scripts/benchmark_site.py derive-key --ref-name "$ref_name")
repo_name="${GITHUB_REPOSITORY#*/}"
site_url_base="https://${GITHUB_REPOSITORY_OWNER}.github.io/${repo_name}"
if [[ "${GITHUB_EVENT_NAME}" == "push" && "${GITHUB_REF_NAME}" == "master" ]]; then
published_variant="all"
else
published_variant="$benchmark_variant"
fi
{
echo "benchmark_variant=$benchmark_variant"
echo "published_variant=$published_variant"
echo "ref_name=$ref_name"
echo "run_sha=$run_sha"
echo "variant_key=$variant_key"
echo "site_url_base=$site_url_base"
} >> "$GITHUB_OUTPUT"
- name: Run benchmark suite
env:
KIDDO_PROFILE_MAX_LOG2_POINTS: "25"
run: |
run_variant() {
case "$1" in
basic)
just bench-v6-eytzinger-focus \
"${{ steps.meta.outputs.variant_key }}" \
./target/benchmark-results \
simd,test_utils,logging_off \
1000
;;
dist)
just bench-v6-dist-metrics \
"${{ steps.meta.outputs.variant_key }}" \
./target/benchmark-results \
1000 \
test_utils,logging_off \
simd,test_utils,logging_off
;;
extended)
just bench-v6-query-family \
"${{ steps.meta.outputs.variant_key }}" \
./target/benchmark-results \
simd,test_utils,logging_off \
1000
;;
leaf)
just bench-v6-leaf-strategies \
"${{ steps.meta.outputs.variant_key }}" \
./target/benchmark-results \
simd,test_utils,logging_off \
1000
;;
stems)
just bench-v6-stem-strategies \
"${{ steps.meta.outputs.variant_key }}" \
./target/benchmark-results \
1000 \
simd,test_utils,logging_off \
simd,test_utils,logging_off
;;
construction)
just bench-v6-construction \
"${{ steps.meta.outputs.variant_key }}" \
./target/benchmark-results \
simd,test_utils,logging_off
;;
*)
echo "Unknown benchmark variant: $1" >&2
exit 2
;;
esac
}
if [[ "${GITHUB_EVENT_NAME}" == "push" && "${GITHUB_REF_NAME}" == "master" ]]; then
run_variant basic
run_variant extended
run_variant dist
run_variant leaf
run_variant stems
run_variant construction
else
run_variant "${{ steps.meta.outputs.benchmark_variant }}"
fi
- name: Upload benchmark results
uses: actions/upload-artifact@v7
with:
name: benchmark-results-${{ github.run_id }}-${{ github.run_attempt }}
path: target/benchmark-results/
if-no-files-found: error
publish:
runs-on: ubuntu-latest
needs: benchmark
steps:
- uses: actions/checkout@v7
with:
show-progress: false
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: "3.12"
- name: Install chart dependencies
run: python -m pip install matplotlib
- name: Install `just`
uses: baptiste0928/cargo-install@v3
with:
crate: just
version: "^1"
- name: Download benchmark artifact
uses: actions/download-artifact@v8
with:
name: benchmark-results-${{ github.run_id }}-${{ github.run_attempt }}
path: ./target/benchmark-results
- name: Prepare gh-pages worktree
run: |
git fetch origin gh-pages || true
rm -rf .benchmark-pages
if git show-ref --verify --quiet refs/remotes/origin/gh-pages; then
git worktree add .benchmark-pages origin/gh-pages
else
checkout_auth=$(git config --get-urlmatch http.extraheader "${GITHUB_SERVER_URL}")
mkdir -p .benchmark-pages
cd .benchmark-pages
git init
git checkout --orphan gh-pages
git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
git config "http.${GITHUB_SERVER_URL}/.extraheader" "$checkout_auth"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
fi
- name: Find open PRs for branch
id: prs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if [[ -n "${{ inputs.pr_number }}" ]]; then
prs='[${{ inputs.pr_number }}]'
else
prs=$(python3 scripts/benchmark_site.py find-prs --repo "${GITHUB_REPOSITORY}" --ref-name "${{ needs.benchmark.outputs.ref_name }}" || echo "[]")
fi
echo "prs=$prs" >> "$GITHUB_OUTPUT"
- name: Migrate legacy v6 gh-pages layout
run: |
mkdir -p ./.benchmark-pages/v6
if [[ ! -e ./.benchmark-pages/v6/baseline && -d ./.benchmark-pages/baseline ]]; then
mv ./.benchmark-pages/baseline ./.benchmark-pages/v6/
fi
if [[ ! -e ./.benchmark-pages/v6/branches && -d ./.benchmark-pages/branches ]]; then
mv ./.benchmark-pages/branches ./.benchmark-pages/v6/
fi
if [[ ! -e ./.benchmark-pages/v6/data && -d ./.benchmark-pages/data ]]; then
mv ./.benchmark-pages/data ./.benchmark-pages/v6/
fi
- name: Publish run into gh-pages tree
env:
PRS_JSON: ${{ steps.prs.outputs.prs }}
run: |
mapfile -t PR_NUMBERS < <(
python3 -c 'import json, os; [print(value) for value in json.loads(os.environ["PRS_JSON"])]'
)
PR_ARGS=()
for pr in "${PR_NUMBERS[@]}"; do
PR_ARGS+=(--pr-number "$pr")
done
python3 scripts/benchmark_site.py publish-run \
--ref-name "${{ needs.benchmark.outputs.ref_name }}" \
--sha "${{ needs.benchmark.outputs.run_sha }}" \
--benchmark-variant "${{ needs.benchmark.outputs.published_variant }}" \
--baseline-ref-name master \
--results-dir ./target/benchmark-results \
--pages-root ./.benchmark-pages/v6 \
--site-url-base '${{ needs.benchmark.outputs.site_url_base }}/v6' \
--summary-path ./target/benchmark-summary.json \
"${PR_ARGS[@]}"
- name: Rebuild top-level benchmark index
run: |
python3 scripts/benchmark_site_root.py \
--pages-root ./.benchmark-pages \
--site-url-base '${{ needs.benchmark.outputs.site_url_base }}'
- name: Commit and push gh-pages
run: |
git -C .benchmark-pages config user.name "github-actions[bot]"
git -C .benchmark-pages config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git -C .benchmark-pages add .
if git -C .benchmark-pages diff --cached --quiet; then
echo "No gh-pages changes to push"
exit 0
fi
git -C .benchmark-pages commit -m "benchmark: publish ${{ needs.benchmark.outputs.ref_name }} ${{ needs.benchmark.outputs.run_sha }}"
git -C .benchmark-pages push origin HEAD:gh-pages
- name: Update sticky PR comments
if: needs.benchmark.outputs.ref_name != 'master'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PRS_JSON: ${{ steps.prs.outputs.prs }}
run: |
python3 -c 'import json, os, subprocess; prs = json.loads(os.environ["PRS_JSON"]); [subprocess.run(["python3", "scripts/benchmark_site.py", "update-pr-comment", "--repo", "${{ github.repository }}", "--pr-number", str(pr), "--summary-path", "./target/benchmark-summary.json", "--site-url-base", "${{ needs.benchmark.outputs.site_url_base }}"], check=True) for pr in prs]'