Skip to content

Commit e3fb863

Browse files
authored
feat: added new GH workflow to measure performance (#22)
2 parents 23b2015 + fd0f635 commit e3fb863

File tree

4 files changed

+446
-65
lines changed

4 files changed

+446
-65
lines changed

.github/workflows/README.md

Lines changed: 120 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,148 @@
1-
# GitHub Actions Workflows
1+
# GitHub Workflows
22

3-
## CI Workflow
3+
This directory contains GitHub Actions workflows for the hash-zig project.
44

5-
The `ci.yml` workflow runs on every push or pull request to `main`, `master`, or `develop` branches.
5+
## Workflows
66

7-
### Jobs
7+
### 1. CI (`ci.yml`)
8+
Runs on every push and pull request to main branches:
9+
- **Lint**: Checks code style and formatting
10+
- **Test**: Runs unit tests on Ubuntu, macOS, and Windows
11+
- **Build Examples**: Ensures all examples compile correctly
812

9-
#### 1. Lint
10-
- **Runs on:** Ubuntu Latest
11-
- **Zig Version:** 0.14.1
12-
- **Steps:**
13-
- Checkout code
14-
- Setup Zig
15-
- Run `zig build lint` (using zlinter)
13+
### 2. Performance Benchmark (`performance-benchmark.yml`)
14+
Runs on pull requests and can be triggered manually:
15+
- **Benchmarks current PR** against the base version
16+
- **Measures key generation, signing, and verification performance**
17+
- **Reports performance improvements** in PR comments
18+
- **Tests multiple lifetimes** (2^10 and 2^16 signatures)
1619

17-
#### 2. Test
18-
- **Runs on:** Ubuntu, macOS, Windows
19-
- **Zig Version:** 0.14.1
20-
- **Matrix Strategy:** Tests on 3 platforms
21-
- **Steps:**
22-
- Checkout code
23-
- Setup Zig
24-
- Run `zig build test`
25-
- Build library with `zig build`
20+
## Performance Benchmarking
2621

27-
#### 3. Build Examples
28-
- **Runs on:** Ubuntu Latest
29-
- **Zig Version:** 0.14.1
30-
- **Dependencies:** Runs after lint and test jobs succeed
31-
- **Steps:**
32-
- Build library
33-
- Run example application
22+
### What it measures
23+
- **Key Generation Time**: Time to generate keypairs for different lifetimes
24+
- **Sign Time**: Time to sign a message
25+
- **Verify Time**: Time to verify a signature
26+
- **Memory Usage**: Implicitly through execution time
3427

35-
### Trigger Events
28+
### How it works
29+
1. **Checkout current PR** and run benchmarks
30+
2. **Checkout base version** (previous commit) and run same benchmarks
31+
3. **Compare results** and calculate percentage improvements
32+
4. **Report results** in GitHub PR summary and console output
3633

37-
The workflow triggers on:
38-
- **Push** to main, master, or develop branches
39-
- **Pull requests** targeting main, master, or develop branches
34+
### Benchmark Results Format
35+
The benchmark outputs results in a structured format:
36+
```
37+
BENCHMARK_RESULT: 2^10:keygen:1.234567
38+
BENCHMARK_RESULT: 2^10:sign:0.000123
39+
BENCHMARK_RESULT: 2^10:verify:0.000456
40+
```
4041

41-
### Badge
42+
### Running Benchmarks Locally
4243

43-
The CI status badge in README.md:
44+
#### Quick Benchmark
45+
```bash
46+
zig build benchmark
47+
```
4448

45-
```markdown
46-
[![CI](https://github.com/ch4r10t33r/hash-zig/actions/workflows/ci.yml/badge.svg)](https://github.com/ch4r10t33r/hash-zig/actions/workflows/ci.yml)
49+
#### Detailed Benchmark with Optimizations
50+
```bash
51+
zig build benchmark -Doptimize=ReleaseFast
4752
```
4853

49-
### Local Testing
54+
#### Custom Benchmark Script
55+
```bash
56+
zig build-exe scripts/benchmark.zig -OReleaseFast --dep hash-zig -Mhash-zig=src/root.zig
57+
./benchmark
58+
```
5059

51-
Before pushing, you can run the same checks locally with Zig 0.14.1:
60+
### Understanding Results
5261

53-
```bash
54-
# Run linting
55-
zig build lint
62+
#### Key Generation
63+
- **2^10 (1,024 signatures)**: Should complete in ~30-60 seconds
64+
- **2^16 (65,536 signatures)**: Should complete in ~5-15 minutes
65+
- **Improvement**: Positive percentage means faster generation
5666

57-
# Run tests
58-
zig build test
67+
#### Sign/Verify
68+
- **Sign**: Should complete in ~100-500ms
69+
- **Verify**: Should complete in ~50-200ms
70+
- **Improvement**: Positive percentage means faster operations
5971

60-
# Build library
61-
zig build
72+
### Performance Targets
6273

63-
# Run example
64-
zig build example
65-
```
74+
Based on the optimization work, we expect:
75+
- **2-3x improvement** in key generation time
76+
- **10-30% improvement** in sign/verify operations
77+
- **Reduced memory allocations** (measured indirectly through speed)
78+
79+
### Troubleshooting
80+
81+
#### Benchmark Fails
82+
1. Check that the code compiles: `zig build -Doptimize=ReleaseFast`
83+
2. Verify tests pass: `zig build test`
84+
3. Check for memory issues on large lifetimes
85+
86+
#### Inconsistent Results
87+
1. Run multiple times to get average
88+
2. Ensure system is not under heavy load
89+
3. Use ReleaseFast optimization mode
90+
91+
#### CI Workflow Issues
92+
1. Check that the base commit exists
93+
2. Verify Zig version compatibility
94+
3. Check artifact upload permissions
95+
96+
### Adding New Benchmarks
97+
98+
To add new performance tests:
99+
100+
1. **Add to benchmark script** (`scripts/benchmark.zig`):
101+
```zig
102+
// New benchmark
103+
const new_start = std.time.nanoTimestamp();
104+
// ... perform operation ...
105+
const new_end = std.time.nanoTimestamp();
106+
const new_duration = @as(f64, @floatFromInt(new_end - new_start)) / 1_000_000_000.0;
107+
std.debug.print("BENCHMARK_RESULT: new_metric:{d:.6}\n", .{new_duration});
108+
```
66109

67-
### Supported Zig Version
110+
2. **Update workflow** to capture new metrics:
111+
```yaml
112+
NEW_METRIC=$(grep "BENCHMARK_RESULT: new_metric:" results.txt | cut -d: -f2)
113+
echo "new_metric=$NEW_METRIC" >> $GITHUB_OUTPUT
114+
```
68115

69-
- **0.14.1** - Required version (zlinter only supports 0.14.x)
116+
3. **Add to performance analysis**:
117+
```yaml
118+
echo "| New Metric | ${{ steps.base.outputs.new_metric }}s | ${{ steps.current.outputs.new_metric }}s | ${improvement}% |" >> $GITHUB_STEP_SUMMARY
119+
```
70120

71-
**Note:** The project uses zlinter which currently only supports Zig 0.14.x. Once zlinter adds support for Zig 0.15+, the CI will be updated.
121+
## Workflow Triggers
72122

73-
### Platform Support
123+
### Automatic Triggers
124+
- **Push to main/master/develop**: Runs CI
125+
- **Pull Request to main/master/develop**: Runs CI + Performance Benchmark
74126

75-
- **Linux** (Ubuntu Latest)
76-
- **macOS** (macOS Latest)
77-
- **Windows** (Windows Latest)
127+
### Manual Triggers
128+
- **Workflow Dispatch**: Can manually trigger performance benchmark
129+
- **API Triggers**: Can be triggered via GitHub API
78130

79-
All tests must pass on all platforms before merging to protected branches.
131+
## Dependencies
80132

81-
### Linter (zlinter)
133+
### Required Tools
134+
- **Zig 0.14.1**: For compilation and testing
135+
- **bc**: For percentage calculations (available in Ubuntu runners)
136+
- **git**: For checking out different versions
82137

83-
The project uses [zlinter](https://github.com/kurtwagner/zlinter) - an extendable Zig linter integrated into the build system.
138+
### Optional Tools
139+
- **perf**: For detailed performance analysis (if needed)
140+
- **valgrind**: For memory profiling (if needed)
84141

85-
**Enabled rules:**
86-
- `field_naming` - Enforce field naming conventions
87-
- `declaration_naming` - Enforce declaration naming conventions (snake_case)
88-
- `function_naming` - Enforce function naming conventions
89-
- `no_unused` - Detect unused declarations
90-
- `no_deprecated` - Warn about deprecated API usage
142+
## Best Practices
91143

92-
**Customization:**
93-
See `build.zig` to add/remove rules or adjust severity levels.
144+
1. **Always use ReleaseFast** for performance benchmarks
145+
2. **Run multiple iterations** for stable results
146+
3. **Document performance targets** in PR descriptions
147+
4. **Include performance context** in commit messages
148+
5. **Monitor trends** over time to catch regressions

0 commit comments

Comments
 (0)