@blinklabs/dingo 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/RELEASE_NOTES.md +67 -0
- package/benchmark_results_targeted.md +63 -0
- package/generate_benchmarks.sh +196 -78
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -527,7 +527,7 @@ especially as there is functionality which has not yet been developed.
|
|
|
527
527
|
|
|
528
528
|
## Development / Building
|
|
529
529
|
|
|
530
|
-
This requires Go 1.
|
|
530
|
+
This requires Go 1.25 or later. You also need `make`.
|
|
531
531
|
|
|
532
532
|
```bash
|
|
533
533
|
# Format, test, and build (default target)
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,5 +1,72 @@
|
|
|
1
1
|
# Release Notes
|
|
2
2
|
|
|
3
|
+
|
|
4
|
+
## v0.23.1 (March 11, 2026)
|
|
5
|
+
|
|
6
|
+
**Title:** Clearer release notes and rock-solid Docker publishing
|
|
7
|
+
|
|
8
|
+
**Date:** March 11, 2026
|
|
9
|
+
|
|
10
|
+
**Version:** v0.23.1
|
|
11
|
+
|
|
12
|
+
Hi folks! Here’s what we shipped in v0.23.1.
|
|
13
|
+
|
|
14
|
+
### ✨ What's New
|
|
15
|
+
|
|
16
|
+
- **Release notes:** Release notes are easier to scan because `RELEASE_NOTES.md` now includes a complete set of notes for v0.23.0.
|
|
17
|
+
|
|
18
|
+
### 💪 Improvements
|
|
19
|
+
|
|
20
|
+
- **Docker publishing (Antithesis image):** Publishing is more consistent because the build pipeline now builds, tags, pushes, and generates an attestation for a Linux amd64-only Antithesis Docker image variant.
|
|
21
|
+
|
|
22
|
+
### 🔧 Fixes
|
|
23
|
+
|
|
24
|
+
- **No fixes:** No user-facing fixes shipped in this patch.
|
|
25
|
+
|
|
26
|
+
### 📋 What You Need to Know
|
|
27
|
+
|
|
28
|
+
- **Upgrade:** You’re all set—no required configuration changes for this release.
|
|
29
|
+
|
|
30
|
+
### 🙏 Thank You
|
|
31
|
+
|
|
32
|
+
Thank you for trying!
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## v0.23.0 (March 10, 2026)
|
|
37
|
+
|
|
38
|
+
**Title:** Overlay-aware validation and a smoother dev mode
|
|
39
|
+
|
|
40
|
+
**Date:** March 10, 2026
|
|
41
|
+
|
|
42
|
+
**Version:** v0.23.0
|
|
43
|
+
|
|
44
|
+
Hi folks! Here’s what we shipped in v0.23.0.
|
|
45
|
+
|
|
46
|
+
### ✨ What's New
|
|
47
|
+
|
|
48
|
+
- **Transaction validation:** Transaction validation is more accurate because ledger and mempool checks now account for pending, in-flight changes with a temporary UTxO overlay.
|
|
49
|
+
|
|
50
|
+
### 💪 Improvements
|
|
51
|
+
|
|
52
|
+
- **Docs:** Setup is easier because `README.md` now includes expanded usage, deployment, and DevNet guidance plus a clear “not for production” warning.
|
|
53
|
+
- **Publish workflow:** Publishing is more rock-solid because the release workflow now targets Node.js `24.x` and pins key GitHub Actions versions.
|
|
54
|
+
- **Release notes:** Release notes are easier to scan because `RELEASE_NOTES.md` now includes v0.22.1 and tightens up transaction validation wording.
|
|
55
|
+
|
|
56
|
+
### 🔧 Fixes
|
|
57
|
+
|
|
58
|
+
- **Connection cleanup:** Connection-related tests are less flaky because keepalive timeouts are deterministic and connection cleanup is safer.
|
|
59
|
+
|
|
60
|
+
### 📋 What You Need to Know
|
|
61
|
+
|
|
62
|
+
- **Dev mode:** If you run dev mode, Dingo will automatically switch the storage mode to API, so check logs if you expected a different mode.
|
|
63
|
+
|
|
64
|
+
### 🙏 Thank You
|
|
65
|
+
|
|
66
|
+
Thank you for trying!
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
3
70
|
## v0.22.1 (March 8, 2026)
|
|
4
71
|
|
|
5
72
|
**Title:** Stability updates and polish
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Dingo Targeted Performance Baseline
|
|
2
|
+
|
|
3
|
+
## Latest Results
|
|
4
|
+
|
|
5
|
+
### Test Environment
|
|
6
|
+
- **Date**: March 10, 2026
|
|
7
|
+
- **Go Version**: 1.25.8
|
|
8
|
+
- **OS**: Linux
|
|
9
|
+
- **Architecture**: aarch64
|
|
10
|
+
- **CPU Cores**: 128
|
|
11
|
+
- **Data Source**: Real immutable testdata blocks from database/immutable/testdata
|
|
12
|
+
- **Scope**: Current optimization baseline for core/api ingest, block processing, and batched load paths
|
|
13
|
+
|
|
14
|
+
### Benchmark Results
|
|
15
|
+
|
|
16
|
+
All benchmarks run with `-benchmem` flag. Iterations are Go benchmark iteration counts; benchmark-specific throughput metrics (for example `blocks/sec`) are reported separately.
|
|
17
|
+
|
|
18
|
+
| Benchmark | Iterations | Time/op | Extra Metrics | Memory/op | Allocs/op |
|
|
19
|
+
|-----------|------------|---------|---------------|-----------|-----------|
|
|
20
|
+
| Block Batch Processing Throughput | 3 | 592689ns | 84361 blocks/sec | 91KB | 2088 |
|
|
21
|
+
| Block Processing Throughput | 3 | 214857ns | 4654 blocks/sec | 26KB | 137 |
|
|
22
|
+
| Block Processing Throughput Predecoded | 3 | 60121ns | 16633 blocks/sec | 2KB | 58 |
|
|
23
|
+
| Raw Block Batch Processing Throughput | 3 | 515408ns | 97011 blocks/sec | 81KB | 1938 |
|
|
24
|
+
| Storage Mode Ingest Steady State/api | 3 | 375174723ns | 479.8 blocks_ingested/sec, 533.1 txs_ingested/sec | 15761KB | 186666 |
|
|
25
|
+
| Storage Mode Ingest Steady State/core | 3 | 152858484ns | 1178 blocks_ingested/sec, 1308 txs_ingested/sec | 7234KB | 94403 |
|
|
26
|
+
| Storage Mode Ingest/api | 3 | 362809147ns | 496.1 blocks_ingested/sec, 551.3 txs_ingested/sec | 15935KB | 193665 |
|
|
27
|
+
| Storage Mode Ingest/core | 3 | 235819272ns | 763.3 blocks_ingested/sec, 848.1 txs_ingested/sec | 7514KB | 101522 |
|
|
28
|
+
## Performance Changes
|
|
29
|
+
|
|
30
|
+
Changes since **March 10, 2026** (initial baseline):
|
|
31
|
+
|
|
32
|
+
### Summary
|
|
33
|
+
- **Faster benchmarks**: 4
|
|
34
|
+
- Block Batch Processing Throughput (+32%)
|
|
35
|
+
- Block Processing Throughput Predecoded (+91%)
|
|
36
|
+
- Storage Mode Ingest Steady State/api (+8%)
|
|
37
|
+
- Storage Mode Ingest Steady State/core (+55%)
|
|
38
|
+
- **Slower benchmarks**: 4
|
|
39
|
+
- Block Processing Throughput (-56%)
|
|
40
|
+
- Raw Block Batch Processing Throughput (-17%)
|
|
41
|
+
- Storage Mode Ingest/api (-18%)
|
|
42
|
+
- Storage Mode Ingest/core (-37%)
|
|
43
|
+
- **New benchmarks**: 0
|
|
44
|
+
- **Removed benchmarks**: 0
|
|
45
|
+
|
|
46
|
+
> **Note**: These are two runs from the same session establishing the baseline.
|
|
47
|
+
> Variance is expected; treat this as a single baseline snapshot, not a regression.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## Historical Results
|
|
51
|
+
|
|
52
|
+
### March 10, 2026
|
|
53
|
+
|
|
54
|
+
| Benchmark | Iterations | Time/op | Extra Metrics | Memory/op | Allocs/op |
|
|
55
|
+
|-----------|------------|---------|---------------|-----------|-----------|
|
|
56
|
+
| Block Batch Processing Throughput | 3 | 781159ns | 64007 blocks/sec | 99KB | 2138 |
|
|
57
|
+
| Block Processing Throughput | 3 | 93495ns | 10696 blocks/sec | 26KB | 138 |
|
|
58
|
+
| Block Processing Throughput Predecoded | 3 | 114562ns | 8729 blocks/sec | 2KB | 60 |
|
|
59
|
+
| Raw Block Batch Processing Throughput | 3 | 427847ns | 116864 blocks/sec | 81KB | 1938 |
|
|
60
|
+
| Storage Mode Ingest Steady State/api | 3 | 406074114ns | 443.3 blocks_ingested/sec, 492.5 txs_ingested/sec | 15743KB | 186725 |
|
|
61
|
+
| Storage Mode Ingest Steady State/core | 3 | 236358805ns | 761.6 blocks_ingested/sec, 846.2 txs_ingested/sec | 7245KB | 94503 |
|
|
62
|
+
| Storage Mode Ingest/api | 3 | 298992974ns | 602.0 blocks_ingested/sec, 668.9 txs_ingested/sec | 15861KB | 193541 |
|
|
63
|
+
| Storage Mode Ingest/core | 3 | 148714628ns | 1210 blocks_ingested/sec, 1345 txs_ingested/sec | 7449KB | 101364 |
|
package/generate_benchmarks.sh
CHANGED
|
@@ -15,11 +15,17 @@
|
|
|
15
15
|
# limitations under the License.
|
|
16
16
|
|
|
17
17
|
# Script to generate benchmark results for Dingo ledger and database with historical tracking
|
|
18
|
-
# Usage: ./generate_benchmarks.sh [output_file] [--write]
|
|
18
|
+
# Usage: ./generate_benchmarks.sh [output_file] [--write] [--bench regex] [--packages pkg1,pkg2] [--benchtime duration] [--title title] [--scope scope] [--data-source source]
|
|
19
19
|
# --write: Write results to file (default: display only)
|
|
20
20
|
|
|
21
21
|
WRITE_TO_FILE=false
|
|
22
22
|
OUTPUT_FILE="benchmark_results.md"
|
|
23
|
+
BENCH_REGEX="."
|
|
24
|
+
BENCH_PACKAGES="./..."
|
|
25
|
+
REPORT_TITLE="Dingo Ledger & Database Benchmark Results"
|
|
26
|
+
REPORT_SCOPE=""
|
|
27
|
+
REPORT_DATA_SOURCE="Real Cardano preview testnet data (40k+ blocks, slots 0-863,996)"
|
|
28
|
+
BENCH_TIME=""
|
|
23
29
|
|
|
24
30
|
# Parse arguments
|
|
25
31
|
while [[ $# -gt 0 ]]; do
|
|
@@ -28,9 +34,39 @@ while [[ $# -gt 0 ]]; do
|
|
|
28
34
|
WRITE_TO_FILE=true
|
|
29
35
|
shift
|
|
30
36
|
;;
|
|
37
|
+
--bench)
|
|
38
|
+
[[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --bench requires a value"; exit 1; }
|
|
39
|
+
BENCH_REGEX="$2"
|
|
40
|
+
shift 2
|
|
41
|
+
;;
|
|
42
|
+
--packages)
|
|
43
|
+
[[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --packages requires a value"; exit 1; }
|
|
44
|
+
BENCH_PACKAGES="$2"
|
|
45
|
+
shift 2
|
|
46
|
+
;;
|
|
47
|
+
--benchtime)
|
|
48
|
+
[[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --benchtime requires a value"; exit 1; }
|
|
49
|
+
BENCH_TIME="$2"
|
|
50
|
+
shift 2
|
|
51
|
+
;;
|
|
52
|
+
--title)
|
|
53
|
+
[[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --title requires a value"; exit 1; }
|
|
54
|
+
REPORT_TITLE="$2"
|
|
55
|
+
shift 2
|
|
56
|
+
;;
|
|
57
|
+
--scope)
|
|
58
|
+
[[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --scope requires a value"; exit 1; }
|
|
59
|
+
REPORT_SCOPE="$2"
|
|
60
|
+
shift 2
|
|
61
|
+
;;
|
|
62
|
+
--data-source)
|
|
63
|
+
[[ -z "${2:-}" || "$2" == -* ]] && { echo "Error: --data-source requires a value"; exit 1; }
|
|
64
|
+
REPORT_DATA_SOURCE="$2"
|
|
65
|
+
shift 2
|
|
66
|
+
;;
|
|
31
67
|
-*)
|
|
32
68
|
echo "Unknown option: $1"
|
|
33
|
-
echo "Usage: $0 [output_file] [--write]"
|
|
69
|
+
echo "Usage: $0 [output_file] [--write] [--bench regex] [--packages pkg1,pkg2] [--benchtime duration] [--title title] [--scope scope] [--data-source source]"
|
|
34
70
|
exit 1
|
|
35
71
|
;;
|
|
36
72
|
*)
|
|
@@ -39,7 +75,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
39
75
|
OUTPUT_FILE="$1"
|
|
40
76
|
OUTPUT_FILE_SET=true
|
|
41
77
|
else
|
|
42
|
-
echo "Too many arguments. Usage: $0 [output_file] [--write]"
|
|
78
|
+
echo "Too many arguments. Usage: $0 [output_file] [--write] [--bench regex] [--packages pkg1,pkg2] [--benchtime duration] [--title title] [--scope scope] [--data-source source]"
|
|
43
79
|
exit 1
|
|
44
80
|
fi
|
|
45
81
|
shift
|
|
@@ -55,7 +91,7 @@ OS=$(uname -s)
|
|
|
55
91
|
ARCH=$(uname -m)
|
|
56
92
|
CPU_CORES=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo "unknown")
|
|
57
93
|
|
|
58
|
-
echo "Running
|
|
94
|
+
echo "Running Dingo benchmarks..."
|
|
59
95
|
echo "==============================="
|
|
60
96
|
|
|
61
97
|
# Run benchmarks with progress output first
|
|
@@ -65,12 +101,17 @@ echo "Executing benchmarks (this may take a few minutes)..."
|
|
|
65
101
|
set -o pipefail
|
|
66
102
|
|
|
67
103
|
# Run go test once, capture output while showing progress
|
|
68
|
-
|
|
104
|
+
IFS=',' read -r -a BENCHMARK_PACKAGE_ARGS <<< "$BENCH_PACKAGES"
|
|
105
|
+
BENCHMARK_ARGS=(-bench="$BENCH_REGEX" -benchmem -run=^$)
|
|
106
|
+
if [[ -n "$BENCH_TIME" ]]; then
|
|
107
|
+
BENCHMARK_ARGS+=("-benchtime=$BENCH_TIME")
|
|
108
|
+
fi
|
|
109
|
+
BENCHMARK_OUTPUT=$(go test "${BENCHMARK_ARGS[@]}" "${BENCHMARK_PACKAGE_ARGS[@]}" 2>&1)
|
|
69
110
|
GO_TEST_EXIT_CODE=$?
|
|
70
111
|
|
|
71
112
|
# Show progress by parsing benchmark names from output
|
|
72
113
|
echo "$BENCHMARK_OUTPUT" | grep "^Benchmark" | sed 's/Benchmark//' | sed 's/-[0-9]*$//' | while read -r name rest; do
|
|
73
|
-
echo "Running: $name
|
|
114
|
+
echo "Running: $name"
|
|
74
115
|
done
|
|
75
116
|
|
|
76
117
|
# Check if go test succeeded
|
|
@@ -90,18 +131,52 @@ parse_benchmark() {
|
|
|
90
131
|
local line="$1"
|
|
91
132
|
local name
|
|
92
133
|
name=$(echo "$line" | awk '{print $1}' | sed 's/Benchmark//' | sed 's/-[0-9]*$//')
|
|
93
|
-
local
|
|
94
|
-
|
|
134
|
+
local iterations
|
|
135
|
+
iterations=$(echo "$line" | awk '{print $2}' | sed 's/,//g')
|
|
95
136
|
local time_val
|
|
96
137
|
time_val=$(echo "$line" | awk '{print $3}')
|
|
97
138
|
local time_unit
|
|
98
139
|
time_unit=$(echo "$line" | awk '{print $4}')
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
local
|
|
102
|
-
|
|
103
|
-
local
|
|
104
|
-
|
|
140
|
+
|
|
141
|
+
local extra_metrics=""
|
|
142
|
+
local mem_op="N/A"
|
|
143
|
+
local allocs_op="N/A"
|
|
144
|
+
local idx=5
|
|
145
|
+
local token_count
|
|
146
|
+
token_count=$(echo "$line" | awk '{print NF}')
|
|
147
|
+
|
|
148
|
+
while [[ $idx -le $token_count ]]; do
|
|
149
|
+
local metric_val
|
|
150
|
+
metric_val=$(echo "$line" | awk -v i="$idx" '{print $i}')
|
|
151
|
+
local metric_unit
|
|
152
|
+
metric_unit=$(echo "$line" | awk -v i="$((idx + 1))" '{print $i}')
|
|
153
|
+
|
|
154
|
+
if [[ -z "$metric_val" || -z "$metric_unit" ]]; then
|
|
155
|
+
break
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
case "$metric_unit" in
|
|
159
|
+
"B/op")
|
|
160
|
+
if [[ "$metric_val" =~ ^[0-9]+$ && $metric_val -gt 1000 ]]; then
|
|
161
|
+
mem_kb=$((metric_val / 1000))
|
|
162
|
+
mem_op="${mem_kb}KB"
|
|
163
|
+
else
|
|
164
|
+
mem_op="${metric_val}B"
|
|
165
|
+
fi
|
|
166
|
+
;;
|
|
167
|
+
"allocs/op")
|
|
168
|
+
allocs_op="$metric_val"
|
|
169
|
+
;;
|
|
170
|
+
*)
|
|
171
|
+
if [[ -n "$extra_metrics" ]]; then
|
|
172
|
+
extra_metrics="${extra_metrics}, "
|
|
173
|
+
fi
|
|
174
|
+
extra_metrics="${extra_metrics}${metric_val} ${metric_unit}"
|
|
175
|
+
;;
|
|
176
|
+
esac
|
|
177
|
+
|
|
178
|
+
idx=$((idx + 2))
|
|
179
|
+
done
|
|
105
180
|
|
|
106
181
|
# Format time
|
|
107
182
|
if [[ "$time_unit" == "ns/op" ]]; then
|
|
@@ -116,62 +191,74 @@ parse_benchmark() {
|
|
|
116
191
|
time_op="${time_val}${time_unit}"
|
|
117
192
|
fi
|
|
118
193
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if [[ $mem_val -gt 1000 ]]; then
|
|
122
|
-
mem_kb=$((mem_val / 1000))
|
|
123
|
-
mem_op="${mem_kb}KB"
|
|
124
|
-
else
|
|
125
|
-
mem_op="${mem_val}B"
|
|
126
|
-
fi
|
|
127
|
-
else
|
|
128
|
-
mem_op="${mem_val}${mem_unit}"
|
|
194
|
+
if [[ -z "$extra_metrics" ]]; then
|
|
195
|
+
extra_metrics="-"
|
|
129
196
|
fi
|
|
130
197
|
|
|
131
198
|
# Format benchmark name nicely
|
|
132
199
|
formatted_name=$(echo "$name" | sed 's/\([A-Z]\)/ \1/g' | sed 's/^ //' | sed 's/NoData$/ (No Data)/' | sed 's/RealData$/ (Real Data)/')
|
|
133
200
|
|
|
134
|
-
echo "$formatted_name|$
|
|
201
|
+
echo "$formatted_name|$iterations|$time_op|$extra_metrics|$mem_op|$allocs_op"
|
|
135
202
|
}
|
|
136
203
|
|
|
137
|
-
# Parse current results into temporary file
|
|
204
|
+
# Parse current results into temporary file, tracking current package
|
|
205
|
+
# go test outputs "pkg: <import-path>" before each package's benchmarks
|
|
138
206
|
CURRENT_RESULTS_FILE=$(mktemp "${TMPDIR:-/tmp}/dingo_bench_XXXXXX")
|
|
207
|
+
current_pkg=""
|
|
139
208
|
while IFS= read -r line; do
|
|
140
|
-
if [[ "$line" =~ ^
|
|
209
|
+
if [[ "$line" =~ ^pkg:[[:space:]]+(.+)$ ]]; then
|
|
210
|
+
current_pkg="${BASH_REMATCH[1]}"
|
|
211
|
+
elif [[ "$line" =~ ^ok[[:space:]] || "$line" =~ ^FAIL[[:space:]] ]]; then
|
|
212
|
+
current_pkg=""
|
|
213
|
+
elif [[ "$line" =~ ^Benchmark ]]; then
|
|
141
214
|
parsed=$(parse_benchmark "$line")
|
|
142
215
|
name=$(echo "$parsed" | cut -d'|' -f1)
|
|
143
216
|
data=$(echo "$parsed" | cut -d'|' -f2-)
|
|
144
|
-
|
|
217
|
+
if [[ -n "$current_pkg" ]]; then
|
|
218
|
+
pkg_short=$(basename "$current_pkg")
|
|
219
|
+
echo "${pkg_short}:${name}|$data" >> "$CURRENT_RESULTS_FILE"
|
|
220
|
+
else
|
|
221
|
+
echo "$name|$data" >> "$CURRENT_RESULTS_FILE"
|
|
222
|
+
fi
|
|
145
223
|
fi
|
|
146
224
|
done <<< "$BENCHMARK_OUTPUT"
|
|
147
225
|
|
|
148
|
-
# Deduplicate benchmark names
|
|
226
|
+
# Deduplicate benchmark names (composite key: package+benchmark)
|
|
149
227
|
sort -t'|' -k1,1 -u "$CURRENT_RESULTS_FILE" > "$CURRENT_RESULTS_FILE.tmp" && mv "$CURRENT_RESULTS_FILE.tmp" "$CURRENT_RESULTS_FILE"
|
|
150
228
|
|
|
151
229
|
# Display current results summary
|
|
152
230
|
echo "Current Benchmark Summary"
|
|
153
231
|
echo "-------------------------"
|
|
154
|
-
echo "
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
ops=$(echo "$line" | awk '{print $2}' | sed 's/,//g')
|
|
158
|
-
echo " - $name: ${ops} ops/sec"
|
|
232
|
+
echo "Most iterations (>100k iters):"
|
|
233
|
+
sort -t'|' -k2,2nr "$CURRENT_RESULTS_FILE" | head -3 | while IFS='|' read -r name iterations _; do
|
|
234
|
+
echo " - $name: ${iterations} iterations"
|
|
159
235
|
done
|
|
160
236
|
|
|
161
237
|
echo ""
|
|
162
|
-
echo "
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
ops=$(echo "$line" | awk '{print $2}' | sed 's/,//g')
|
|
166
|
-
echo " - $name: ${ops} ops/sec"
|
|
238
|
+
echo "Fewest iterations (<1k iters):"
|
|
239
|
+
awk -F'|' '$2 < 1000 {print $1 "|" $2}' "$CURRENT_RESULTS_FILE" | while IFS='|' read -r name iterations; do
|
|
240
|
+
echo " - $name: ${iterations} iterations"
|
|
167
241
|
done
|
|
168
242
|
|
|
169
243
|
echo ""
|
|
170
244
|
echo "Memory usage:"
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
245
|
+
awk -F'|' '
|
|
246
|
+
function mem_bytes(v) {
|
|
247
|
+
if (v ~ /KB$/) {
|
|
248
|
+
sub(/KB$/, "", v)
|
|
249
|
+
return v + 0
|
|
250
|
+
}
|
|
251
|
+
if (v ~ /B$/) {
|
|
252
|
+
sub(/B$/, "", v)
|
|
253
|
+
return (v + 0) / 1000
|
|
254
|
+
}
|
|
255
|
+
return -1
|
|
256
|
+
}
|
|
257
|
+
{
|
|
258
|
+
print mem_bytes($5) "|" $1 "|" $5
|
|
259
|
+
}
|
|
260
|
+
' "$CURRENT_RESULTS_FILE" | sort -t'|' -k1,1nr | head -3 | while IFS='|' read -r _ name mem; do
|
|
261
|
+
echo " - $name: ${mem} per op"
|
|
175
262
|
done
|
|
176
263
|
|
|
177
264
|
# Read previous results if file exists and we're comparing
|
|
@@ -193,19 +280,39 @@ if [[ -f "$OUTPUT_FILE" && "$WRITE_TO_FILE" == "true" ]]; then
|
|
|
193
280
|
if [[ "$line" == "## Performance Changes" || "$line" == "## Historical Results" ]]; then
|
|
194
281
|
break
|
|
195
282
|
fi
|
|
196
|
-
if [[ "$line" == "| Benchmark | Operations/sec | Time/op | Memory/op | Allocs/op |"
|
|
283
|
+
if [[ "$line" == "| Benchmark | Operations/sec | Time/op | Memory/op | Allocs/op |" ||
|
|
284
|
+
"$line" == "| Benchmark | Iterations | Time/op | Extra Metrics | Memory/op | Allocs/op |" ]]; then
|
|
197
285
|
in_table=true
|
|
198
286
|
continue
|
|
199
287
|
fi
|
|
200
|
-
|
|
288
|
+
# Skip separator rows (e.g. |---|---|...)
|
|
289
|
+
if [[ "$line" =~ ^\|[-[:space:]\|]+\|$ ]]; then
|
|
290
|
+
continue
|
|
291
|
+
fi
|
|
292
|
+
if [[ "$in_table" == true && "$line" =~ ^\|.*\|.*\|.*\|.*\|.*\|$ ]]; then
|
|
201
293
|
# Parse table row
|
|
202
294
|
benchmark=$(echo "$line" | sed 's/^| //' | cut -d'|' -f1 | sed 's/ *$//')
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
295
|
+
# Count fields to detect 5-column vs 6-column format
|
|
296
|
+
field_count=$(echo "$line" | awk -F'|' '{print NF - 2}')
|
|
297
|
+
|
|
298
|
+
if [[ "$field_count" -le 5 ]]; then
|
|
299
|
+
# Old 5-column format: Benchmark | Operations/sec | Time/op | Memory/op | Allocs/op
|
|
300
|
+
iterations="-"
|
|
301
|
+
time_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f3 | sed 's/ //g')
|
|
302
|
+
extra_metrics=$(echo "$line" | sed 's/^| //' | cut -d'|' -f2 | sed 's/^ *//' | sed 's/ *$//')
|
|
303
|
+
mem_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f4 | sed 's/ //g')
|
|
304
|
+
allocs_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f5 | sed 's/ //g')
|
|
305
|
+
else
|
|
306
|
+
# Current 6-column format
|
|
307
|
+
iterations=$(echo "$line" | sed 's/^| //' | cut -d'|' -f2 | sed 's/ //g' | sed 's/,//g')
|
|
308
|
+
time_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f3 | sed 's/ //g')
|
|
309
|
+
extra_metrics=$(echo "$line" | sed 's/^| //' | cut -d'|' -f4 | sed 's/^ *//' | sed 's/ *$//')
|
|
310
|
+
mem_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f5 | sed 's/ //g')
|
|
311
|
+
allocs_op=$(echo "$line" | sed 's/^| //' | cut -d'|' -f6 | sed 's/ //g')
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
if [[ -n "$benchmark" && -n "$time_op" ]]; then
|
|
315
|
+
echo "$benchmark|$iterations|$time_op|$extra_metrics|$mem_op|$allocs_op" >> "$PREVIOUS_RESULTS_FILE"
|
|
209
316
|
fi
|
|
210
317
|
fi
|
|
211
318
|
if [[ "$in_table" == true && "$line" == "" ]]; then
|
|
@@ -251,16 +358,16 @@ if [[ -n "$previous_date" && "$WRITE_TO_FILE" == "true" ]]; then
|
|
|
251
358
|
current_data=$(get_current_data "$benchmark")
|
|
252
359
|
previous_data=$(get_previous_data "$benchmark")
|
|
253
360
|
|
|
254
|
-
|
|
255
|
-
|
|
361
|
+
current_iters=$(echo "$current_data" | cut -d'|' -f1)
|
|
362
|
+
previous_iters=$(echo "$previous_data" | cut -d'|' -f1)
|
|
256
363
|
|
|
257
|
-
if [[ "$
|
|
258
|
-
change=$(( (
|
|
364
|
+
if [[ "$current_iters" =~ ^[0-9]+$ && "$previous_iters" =~ ^[0-9]+$ && $previous_iters -gt 0 ]]; then
|
|
365
|
+
change=$(( (current_iters - previous_iters) * 100 / previous_iters ))
|
|
259
366
|
if [[ $change -gt 10 ]]; then
|
|
260
367
|
faster_benchmarks="$faster_benchmarks
|
|
261
368
|
$benchmark (+${change}%)"
|
|
262
369
|
elif [[ $change -lt -10 ]]; then
|
|
263
|
-
change_abs=$(( (
|
|
370
|
+
change_abs=$(( (previous_iters - current_iters) * 100 / previous_iters ))
|
|
264
371
|
slower_benchmarks="$slower_benchmarks
|
|
265
372
|
$benchmark (-${change_abs}%)"
|
|
266
373
|
MAJOR_CHANGES=true
|
|
@@ -333,16 +440,16 @@ if [[ "$WRITE_TO_FILE" == "true" ]]; then
|
|
|
333
440
|
current_data=$(get_current_data "$benchmark")
|
|
334
441
|
previous_data=$(get_previous_data "$benchmark")
|
|
335
442
|
|
|
336
|
-
|
|
337
|
-
|
|
443
|
+
current_iters=$(echo "$current_data" | cut -d'|' -f1)
|
|
444
|
+
previous_iters=$(echo "$previous_data" | cut -d'|' -f1)
|
|
338
445
|
|
|
339
|
-
if [[ "$
|
|
340
|
-
if [[ $
|
|
341
|
-
change=$(( (
|
|
446
|
+
if [[ "$current_iters" =~ ^[0-9]+$ && "$previous_iters" =~ ^[0-9]+$ && $previous_iters -gt 0 ]]; then
|
|
447
|
+
if [[ $current_iters -gt $previous_iters ]]; then
|
|
448
|
+
change=$(( (current_iters - previous_iters) * 100 / previous_iters ))
|
|
342
449
|
faster_benchmarks="$faster_benchmarks
|
|
343
450
|
$benchmark (+${change}%)"
|
|
344
|
-
elif [[ $
|
|
345
|
-
change=$(( (
|
|
451
|
+
elif [[ $current_iters -lt $previous_iters ]]; then
|
|
452
|
+
change=$(( (previous_iters - current_iters) * 100 / previous_iters ))
|
|
346
453
|
slower_benchmarks="$slower_benchmarks
|
|
347
454
|
$benchmark (-${change}%)"
|
|
348
455
|
fi
|
|
@@ -401,7 +508,7 @@ $benchmark"
|
|
|
401
508
|
|
|
402
509
|
# Create the markdown file
|
|
403
510
|
cat > "$OUTPUT_FILE.tmp" << EOF
|
|
404
|
-
#
|
|
511
|
+
# $REPORT_TITLE
|
|
405
512
|
|
|
406
513
|
## Latest Results
|
|
407
514
|
|
|
@@ -411,24 +518,34 @@ $benchmark"
|
|
|
411
518
|
- **OS**: $OS
|
|
412
519
|
- **Architecture**: $ARCH
|
|
413
520
|
- **CPU Cores**: $CPU_CORES
|
|
414
|
-
- **Data Source**:
|
|
521
|
+
- **Data Source**: $REPORT_DATA_SOURCE
|
|
522
|
+
EOF
|
|
523
|
+
|
|
524
|
+
if [[ -n "$REPORT_SCOPE" ]]; then
|
|
525
|
+
cat >> "$OUTPUT_FILE.tmp" << EOF
|
|
526
|
+
- **Scope**: $REPORT_SCOPE
|
|
527
|
+
EOF
|
|
528
|
+
fi
|
|
529
|
+
|
|
530
|
+
cat >> "$OUTPUT_FILE.tmp" << EOF
|
|
415
531
|
|
|
416
532
|
### Benchmark Results
|
|
417
533
|
|
|
418
|
-
All benchmarks run with \`-benchmem\` flag
|
|
534
|
+
All benchmarks run with \`-benchmem\` flag. Iterations are Go benchmark iteration counts; benchmark-specific throughput metrics (for example \`blocks/sec\`) are reported separately.
|
|
419
535
|
|
|
420
|
-
| Benchmark |
|
|
421
|
-
|
|
536
|
+
| Benchmark | Iterations | Time/op | Extra Metrics | Memory/op | Allocs/op |
|
|
537
|
+
|-----------|------------|---------|---------------|-----------|-----------|
|
|
422
538
|
EOF
|
|
423
539
|
|
|
424
540
|
# Add current results to table
|
|
425
541
|
while IFS= read -r benchmark; do
|
|
426
542
|
data=$(get_current_data "$benchmark")
|
|
427
|
-
|
|
543
|
+
iterations=$(echo "$data" | cut -d'|' -f1)
|
|
428
544
|
time_op=$(echo "$data" | cut -d'|' -f2)
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
echo "
|
|
545
|
+
extra_metrics=$(echo "$data" | cut -d'|' -f3)
|
|
546
|
+
mem_op=$(echo "$data" | cut -d'|' -f4)
|
|
547
|
+
allocs_op=$(echo "$data" | cut -d'|' -f5)
|
|
548
|
+
echo "| $benchmark | $iterations | $time_op | $extra_metrics | $mem_op | $allocs_op |" >> "$OUTPUT_FILE.tmp"
|
|
432
549
|
done < <(list_current_benchmarks)
|
|
433
550
|
|
|
434
551
|
# Add comparison section
|
|
@@ -441,17 +558,18 @@ EOF
|
|
|
441
558
|
echo "" >> "$OUTPUT_FILE.tmp"
|
|
442
559
|
echo "### $previous_date" >> "$OUTPUT_FILE.tmp"
|
|
443
560
|
echo "" >> "$OUTPUT_FILE.tmp"
|
|
444
|
-
echo "| Benchmark |
|
|
445
|
-
echo "
|
|
561
|
+
echo "| Benchmark | Iterations | Time/op | Extra Metrics | Memory/op | Allocs/op |" >> "$OUTPUT_FILE.tmp"
|
|
562
|
+
echo "|-----------|------------|---------|---------------|-----------|-----------|" >> "$OUTPUT_FILE.tmp"
|
|
446
563
|
|
|
447
564
|
# Add previous results
|
|
448
565
|
while IFS= read -r benchmark; do
|
|
449
566
|
data=$(get_previous_data "$benchmark")
|
|
450
|
-
|
|
567
|
+
iterations=$(echo "$data" | cut -d'|' -f1)
|
|
451
568
|
time_op=$(echo "$data" | cut -d'|' -f2)
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
echo "
|
|
569
|
+
extra_metrics=$(echo "$data" | cut -d'|' -f3)
|
|
570
|
+
mem_op=$(echo "$data" | cut -d'|' -f4)
|
|
571
|
+
allocs_op=$(echo "$data" | cut -d'|' -f5)
|
|
572
|
+
echo "| $benchmark | $iterations | $time_op | $extra_metrics | $mem_op | $allocs_op |" >> "$OUTPUT_FILE.tmp"
|
|
455
573
|
done < <(list_previous_benchmarks)
|
|
456
574
|
fi
|
|
457
575
|
|