Skip to content

Commit

Permalink
Publish benchmark results
Browse files Browse the repository at this point in the history
  • Loading branch information
reubeno committed May 12, 2024
1 parent 09e92a8 commit 0ba0ad6
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,18 @@ jobs:
run: cargo bench --workspace -- --output-format bencher | tee benchmarks.txt
working-directory: main

- name: Compare benchmark results
run: |
./scripts/compare-benchmark-results.py -b main/benchmarks.txt -t pr/benchmarks.txt >benchmark-results.md
- name: Upload performance results
uses: actions/upload-artifact@v4
with:
name: perf-reports
path: |
pr/benchmarks.txt
main/benchmarks.txt
benchmark-results.md
# - name: Compare benchmark results
# uses: openpgpjs/github-action-pull-request-benchmark@v1
Expand Down
74 changes: 74 additions & 0 deletions scripts/compare-benchmark-results.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/python3
import argparse
import datetime
import re
from dataclasses import dataclass
from typing import Dict

parser = argparse.ArgumentParser()
parser.add_argument("-b", "--base-results", dest="base_results_file_path", type=str, help="Path to base results output file", required=True)
parser.add_argument("-t", "--test-results", dest="test_results_file_path", type=str, help="Path to test results output file", required=True)

args = parser.parse_args()

@dataclass
class Benchmark:
test_name: str
duration_in_ns: int
deviation_in_ns: int

def parse_benchmarks_results(file_path: str) -> Dict[str, Benchmark]:
benchmarks = {}

with open(file_path, "r") as file:
for line in file.readlines():
match = re.match(r"test (.*) \.\.\. bench: +(\d+) ns/iter \(\+/- (\d+)\)", line.strip())
if match:
benchmark = Benchmark(
test_name=match.group(1),
duration_in_ns=int(match.group(2)),
deviation_in_ns=int(match.group(3))
)

benchmarks[benchmark.test_name] = benchmark

return benchmarks

base_results = parse_benchmarks_results(args.base_results_file_path)
test_results = parse_benchmarks_results(args.test_results_file_path)

base_test_names = set(base_results.keys())
test_test_names = set(test_results.keys())

removed_from_base = base_test_names - test_test_names
added_by_test = test_test_names - base_test_names
common = base_test_names & test_test_names

if common:
print(f"| {'Benchmark name':36} | {'Baseline (ns)':>13} | {'Test/PR (ns)':>13} | {'Delta (ns)':>13} | {'Delta %'} |")
print(f"| {'-' * 36} | {'-' * 13} | {'-' * 13} | {'-' * 13} | {'-' * 7}")
for name in sorted(common):
base_duration = base_results[name].duration_in_ns
test_duration = test_results[name].duration_in_ns

delta_duration = test_duration - base_duration
delta_str = str(delta_duration)
if delta_duration > 0:
delta_str = "+" + delta_str

delta_percentage = (100.0 * delta_duration) / base_duration
delta_percentage_str = f"{delta_percentage:.2f}%"
if delta_percentage > 0:
delta_percentage_str = "+" + delta_percentage_str

print(f"| {name:36} | {base_duration:10} ns | {test_duration:10} ns | {delta_str:>10} ns | {delta_percentage_str:>7} |")

if removed_from_base:
print("Benchmarks removed:")
for name in removed_from_base:
print(f" - {name}")

if added_by_test:
print("Benchmarks added:")
for name in added_by_test:
print(f" - {name}")

0 comments on commit 0ba0ad6

Please sign in to comment.