Skip to content

Commit e6f2ac8

Browse files
authored
Add perf-diff-stats just recipe (#7480)
## Description This PR adds the `perf-diff-stats` recipe to the `justfile`. The recipe calculates a simple statistics of performance improvements and regressions obtained from the `perf-diff` recipe. The statistics contains the _count_, _average_, _median_, _max_, and _min_ of improvements and regressions and can be used to easily communicate performance differences gained in a PR. E.g.: | | Improvements | Regressions | | - | -: | -: | | Count | 3 | 4 | | Average | 8.13% | -2.21% | | Median | 7.05% | -1.07% | | Max | 12.86% | -6.12% | | Min | 4.47% | -0.59% | ## Checklist - [ ] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
1 parent dd0ee9b commit e6f2ac8

File tree

5 files changed

+114
-4
lines changed

5 files changed

+114
-4
lines changed

justfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ alias pd := perf-diff
6767
perf-diff before after format='md':
6868
./scripts/perf/perf-diff.sh "{{before}}" "{{after}}" "{{format}}"
6969

70+
alias pds := perf-diff-stats
71+
# generate performance statistics summary from a `perf-diff` output CSV file
72+
[group('performance')]
73+
perf-diff-stats diff_file:
74+
cat "{{diff_file}}" | ./scripts/perf/perf-diff-stats.sh
75+
7076
alias pdl := perf-diff-latest
7177
# generate performance diffs between the latest two CSV files per testing category
7278
[group('performance')]

scripts/perf/perf-diff-latest.sh

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
output_format="${1:-md}"
99
perf_out_dir="./test/perf_out"
1010
perf_diff_script="./scripts/perf/perf-diff.sh"
11+
perf_diff_stats_script="./scripts/perf/perf-diff-stats.sh"
1112

1213
categories=("e2e-gas-usages" "e2e-bytecode-sizes" "in-language-gas-usages" "in-language-bytecode-sizes")
1314

@@ -70,15 +71,19 @@ process_category() {
7071
after_ts="${after_base%%-*}"
7172
now_ts="$(date '+%m%d%H%M%S')"
7273

73-
outfile="${perf_out_dir}/${now_ts}-diff-${category}-${before_ts}-vs-${after_ts}.${output_format}"
74+
diff_outfile="${perf_out_dir}/${now_ts}-diff-${category}-${before_ts}-vs-${after_ts}.${output_format}"
75+
stats_outfile="${perf_out_dir}/${now_ts}-stats-${category}-${before_ts}-vs-${after_ts}.md"
7476

7577
echo "Comparing '$category':"
7678
echo " before: $before_file"
7779
echo " after: $after_file"
78-
echo "Diff written to: $outfile"
80+
echo "Diff written to: $diff_outfile"
81+
echo "Stats written to: $stats_outfile"
7982
echo
8083

81-
"$perf_diff_script" "$before_file" "$after_file" "$output_format" | tee "$outfile"
84+
"$perf_diff_script" "$before_file" "$after_file" csv | "$perf_diff_stats_script" | tee "$stats_outfile"
85+
echo
86+
"$perf_diff_script" "$before_file" "$after_file" "$output_format" | tee "$diff_outfile"
8287
echo
8388
}
8489

scripts/perf/perf-diff-stats.sh

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/bin/bash
2+
3+
# This script calculates a simple statistical summary of performance differences
4+
# collected from two CSV files, by using `perf-diff.sh` to compute the diffs first.
5+
#
6+
# The summary includes count, average, median, max, min of improvements and regressions
7+
# (percentage changes), and outputs the result as a Markdown table.
8+
#
9+
# Usage, e.g.: `cat <output of perf-diff.sh> | perf-diff-stats.sh`.
10+
11+
set -euo pipefail
12+
13+
# Force C locale so both parsing and sorting use '.' as decimal separator.
14+
export LC_ALL=C
15+
16+
tmp_all="$(mktemp)"; trap 'rm -f "$tmp_all" "$posf" "$negf" "$pos_sorted" "$neg_sorted"' EXIT
17+
posf="$(mktemp)"
18+
negf="$(mktemp)"
19+
pos_sorted="$(mktemp)"
20+
neg_sorted="$(mktemp)"
21+
22+
# Stash stdin for multiple passes.
23+
cat > "$tmp_all"
24+
25+
# Extract normalized numeric values from the fourth column.
26+
awk -F',' -v POS="$posf" -v NEG="$negf" '
27+
NR==1 { next } # skip header
28+
{
29+
v = $4
30+
v += 0
31+
if (v > 0) {
32+
print v >> POS
33+
} else if (v < 0) {
34+
print (-v) >> NEG
35+
}
36+
}
37+
' "$tmp_all"
38+
39+
# Calculate stats (avg, min, max, count) for a one-column file.
40+
stats() {
41+
local file="$1"
42+
if [[ ! -s "$file" ]]; then
43+
# no values
44+
echo "— — — 0"
45+
return
46+
fi
47+
awk '
48+
NR==1 { min=$1; max=$1; sum=$1; c=1; next }
49+
{ if($1<min) min=$1; if($1>max) max=$1; sum+=$1; c++ }
50+
END { printf("%.2f %.2f %.2f %d\n", sum/c, min, max, c) }
51+
' "$file"
52+
}
53+
54+
# Calculate median for a one-column file (sorted numerically first).
55+
median() {
56+
local file="$1"
57+
if [[ ! -s "$file" ]]; then
58+
echo ""
59+
return
60+
fi
61+
sort -n "$file" > "$file.sorted.$$"
62+
awk '
63+
{ a[++n]=$1 }
64+
END {
65+
if (n==0) { print "—"; exit }
66+
if (n%2==1) {
67+
printf("%.2f\n", a[(n+1)/2])
68+
} else {
69+
printf("%.2f\n", (a[n/2]+a[n/2+1])/2)
70+
}
71+
}
72+
' "$file.sorted.$$"
73+
rm -f "$file.sorted.$$"
74+
}
75+
76+
# Compute stats.
77+
read -r p_avg p_min p_max p_cnt <<<"$(stats "$posf")"
78+
read -r n_avg n_min n_max n_cnt <<<"$(stats "$negf")"
79+
80+
# Compute medians.
81+
cp "$posf" "$pos_sorted" 2>/dev/null || true
82+
cp "$negf" "$neg_sorted" 2>/dev/null || true
83+
p_med="$(median "$pos_sorted")"
84+
n_med="$(median "$neg_sorted")"
85+
86+
# Print a table cell value or em-dash.
87+
fmt_cnt() { [[ "$1" == "0" ]] && echo "" || printf "%d" "$1"; }
88+
fmt_imp() { [[ "$1" == "" ]] && echo "" || printf "%.2f%%" "$1"; }
89+
fmt_reg() { [[ "$1" == "" ]] && echo "" || printf "%.2f%%" "-$1"; }
90+
91+
# Print the summary table.
92+
echo "| | Improvements | Regressions |"
93+
echo "| - | -: | -: |"
94+
printf "| Count | %s | %s |\n" "$(fmt_cnt "$p_cnt")" "$(fmt_cnt "$n_cnt")"
95+
printf "| Average | %s | %s |\n" "$(fmt_imp "$p_avg")" "$(fmt_reg "$n_avg")"
96+
printf "| Median | %s | %s |\n" "$(fmt_imp "$p_med")" "$(fmt_reg "$n_med")"
97+
printf "| Max | %s | %s |\n" "$(fmt_imp "$p_max")" "$(fmt_reg "$n_max")"
98+
printf "| Min | %s | %s |\n" "$(fmt_imp "$p_min")" "$(fmt_reg "$n_min")"

scripts/perf/perf-diff.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ if [ "$output_format" == "csv" ]; then
4545
echo "Test,Before,After,Percentage"
4646
else
4747
echo "| Test | Before | After | Percentage |"
48-
echo "|------|--------|-------|------------|"
48+
echo "| ---- | -----: | ----: | ---------: |"
4949
fi
5050

5151
paste -d, "$before_file" "$after_file" | while IFS=',' read -r test1 before test2 after; do

test/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ perf-e2e filter='' # collect gas usages and bytecode sizes fr
172172
perf-in-lang filter='' # collect gas usages from in-language tests [alias: pil]
173173
perf-all filter='' # collect gas usages and bytecode sizes from all tests (E2E and in-language) [alias: pa]
174174
perf-diff before after format='md' # generate performance diff between two CSV files [alias: pd]
175+
perf-diff-stats diff_file # generate performance statistics summary from a `perf-diff` output CSV file [alias: pds]
175176
perf-diff-latest format='md' # generate performance diffs between the latest two CSV files per testing category [alias: pdl]
176177
perf-snapshot-historical path open='' # collect historic gas usages from a snapshot test that has a `forc test` output [alias: psh]
177178
perf-list # list all performance files (*gas-usages-*.* and *bytecode-sizes-*.*) [alias: pl]

0 commit comments

Comments
 (0)