Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
50 changes: 8 additions & 42 deletions .github/workflows/bench.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,55 +125,21 @@ jobs:
runs-on: ubuntu-latest
needs: [linux, windows]
steps:
- uses: actions/checkout@v4

- name: Download benchmark artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
pattern: benchmark-*

- name: Prepare Pages content
shell: bash
run: |
set -euo pipefail
RUN_ID="${GITHUB_RUN_ID}"
OUT_DIR="site/benchmarks/runs/${RUN_ID}"

mkdir -p "${OUT_DIR}"

# Keep artifact directories separated to avoid collisions.
for d in artifacts/*; do
if [ -d "$d" ]; then
name="$(basename "$d")"
mkdir -p "${OUT_DIR}/${name}"
cp -R "$d"/* "${OUT_DIR}/${name}"/ || true
fi
done

# No Jekyll processing (serve files as-is)
touch site/.nojekyll

# Write pointer to the latest run.
python3 - <<'PY'
import json, os
repo = os.environ.get('GITHUB_REPOSITORY', '')
run_id = int(os.environ.get('GITHUB_RUN_ID', '0'))
run_url = f"https://github.com/{repo}/actions/runs/{run_id}" if repo and run_id else None
artifacts_dir = 'artifacts'
artifacts = []
if os.path.isdir(artifacts_dir):
for name in sorted(os.listdir(artifacts_dir)):
full = os.path.join(artifacts_dir, name)
if os.path.isdir(full) and name.startswith('benchmark-'):
artifacts.append(name)
data = {
'runId': run_id,
'runUrl': run_url,
'artifacts': artifacts,
}
os.makedirs('site/benchmarks', exist_ok=True)
with open('site/benchmarks/latest.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
PY
run: >-
python3 scripts/publish_benchmarks_to_pages.py
--artifacts-dir artifacts
--site-dir site
--repo "${{ github.repository }}"
--run-id "${{ github.run_id }}"

- name: Deploy to gh-pages
uses: peaceiris/actions-gh-pages@v4
Expand Down
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,6 @@ This library is header-only, so you only need to specify the include path.
g++ -I ./libcpprime -O3 Main.cpp
```

# Benchmarks

The benchmark is run on GitHub Actions' Linux with gcc with -O3 optimization enabled.

You can find more detailed benchmark results by clicking [here](https://github.com/Rac75116/libcpprime/actions/workflows/bench.yml?query=branch%3Amain+is%3Acompleted).

# Releases

- 2025/12/21 ver 1.3.0
Expand Down
104 changes: 104 additions & 0 deletions scripts/publish_benchmarks_to_pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env python3

from __future__ import annotations

import argparse
import json
import shutil
import zipfile
from pathlib import Path


def _safe_rmtree(path: Path) -> None:
if path.exists():
shutil.rmtree(path)


def _copy_tree(src: Path, dst: Path) -> None:
dst.mkdir(parents=True, exist_ok=True)
for item in src.iterdir():
target = dst / item.name
if item.is_dir():
shutil.copytree(item, target, dirs_exist_ok=True)
else:
shutil.copy2(item, target)


def _extract_zip(zip_path: Path, dst: Path) -> None:
dst.mkdir(parents=True, exist_ok=True)
with zipfile.ZipFile(zip_path) as z:
z.extractall(dst)


def main() -> int:
parser = argparse.ArgumentParser(
description="Publish benchmark artifacts to GitHub Pages (fixed latest path)."
)
parser.add_argument("--artifacts-dir", required=True)
parser.add_argument("--site-dir", required=True)
parser.add_argument("--repo", required=True, help="owner/repo")
parser.add_argument("--run-id", required=True)
args = parser.parse_args()

artifacts_dir = Path(args.artifacts_dir)
site_dir = Path(args.site_dir)

repo = args.repo
run_id = int(args.run_id)
run_url = (
f"https://github.com/{repo}/actions/runs/{run_id}" if repo and run_id else None
)

# Fixed, always-latest path.
benchmarks_dir = site_dir / "benchmarks"
latest_dir = benchmarks_dir / "latest"

# Start fresh to avoid stale files from older runs.
latest_dir.mkdir(parents=True, exist_ok=True)
_safe_rmtree(latest_dir)
latest_dir.mkdir(parents=True, exist_ok=True)

published_artifacts: list[str] = []

if artifacts_dir.exists():
for entry in sorted(artifacts_dir.iterdir(), key=lambda p: p.name):
name = entry.name

if entry.is_dir():
# actions/download-artifact typically extracts into a directory per artifact.
if not name.startswith("benchmark-"):
continue
_copy_tree(entry, latest_dir / name)
published_artifacts.append(name)
continue

if entry.is_file() and entry.suffix.lower() == ".zip":
base = entry.stem
if not base.startswith("benchmark-"):
continue
_extract_zip(entry, latest_dir / base)
published_artifacts.append(base)
continue

# No Jekyll processing (serve files as-is)
site_dir.mkdir(parents=True, exist_ok=True)
(site_dir / ".nojekyll").write_text("", encoding="utf-8")

benchmarks_dir.mkdir(parents=True, exist_ok=True)

latest_json = {
"runId": run_id,
"runUrl": run_url,
"artifacts": published_artifacts,
"baseUrl": "/benchmarks/latest",
}

(benchmarks_dir / "latest.json").write_text(
json.dumps(latest_json, ensure_ascii=False, indent=2) + "\n", encoding="utf-8"
)

return 0


if __name__ == "__main__":
raise SystemExit(main())