Skip to content

Commit 1936ce5

Browse files
committed
Add Codespeed and benchmark routine
1 parent 2506a90 commit 1936ce5

11 files changed

Lines changed: 869 additions & 8 deletions

File tree

.github/workflows/codspeed.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: CodSpeed
2+
3+
on:
4+
# Run on pushes to main branch
5+
push:
6+
branches: [ main ]
7+
8+
# Run on pull requests to main branch
9+
pull_request:
10+
branches: [ main ]
11+
12+
jobs:
13+
benchmarks:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Install system dependencies
21+
run: sudo apt-get update && sudo apt-get install -y libfontconfig1-dev pkg-config
22+
23+
- name: Set up Rust
24+
uses: dtolnay/rust-toolchain@stable
25+
with:
26+
components: rustfmt, clippy
27+
28+
- name: Cache Rust dependencies
29+
uses: actions/cache@v4
30+
with:
31+
path: |
32+
~/.cargo/bin/
33+
~/.cargo/registry/index/
34+
~/.cargo/registry/cache/
35+
~/.cargo/git/db/
36+
target/
37+
key: ${{ runner.os }}-cargo-bench-${{ hashFiles('**/Cargo.lock') }}
38+
restore-keys: |
39+
${{ runner.os }}-cargo-bench-
40+
${{ runner.os }}-cargo-
41+
42+
- name: Build project
43+
run: cargo build --release
44+
45+
- name: Run benchmarks
46+
uses: CodSpeedHQ/action@v3
47+
with:
48+
run: cargo bench --bench commutations --bench mortality_functions --bench annuities
49+
token: ${{ secrets.CODSPEED_TOKEN }}
50+
51+
- name: Upload benchmark results
52+
if: github.event_name == 'pull_request'
53+
uses: actions/upload-artifact@v4
54+
with:
55+
name: benchmark-results
56+
path: target/criterion/

.github/workflows/rust-1.89.0.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Rust 1.89.0 CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build-and-test-1-89-0:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Install system dependencies
15+
run: sudo apt-get update && sudo apt-get install -y libfontconfig1-dev pkg-config
16+
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Set up Rust 1.89.0
21+
uses: dtolnay/rust-toolchain@master
22+
with:
23+
toolchain: '1.89.0'
24+
components: rustfmt, clippy
25+
26+
- name: Build
27+
run: cargo build --verbose
28+
29+
- name: Run tests
30+
run: cargo test --all --verbose
31+
32+
- name: Run clippy (linter)
33+
run: cargo clippy --all -- -D warnings
34+
35+
- name: Run fmt (format check)
36+
run: cargo fmt --all -- --check

.github/workflows/rust-nightly.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Rust Nightly CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build-and-test-nightly:
11+
runs-on: ubuntu-latest
12+
continue-on-error: true # Allow nightly builds to fail without failing the entire workflow
13+
14+
steps:
15+
- name: Install system dependencies
16+
run: sudo apt-get update && sudo apt-get install -y libfontconfig1-dev pkg-config
17+
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Set up Rust Nightly
22+
uses: dtolnay/rust-toolchain@nightly
23+
with:
24+
components: rustfmt, clippy
25+
26+
- name: Build
27+
run: cargo build --verbose
28+
29+
- name: Run tests
30+
run: cargo test --all --verbose
31+
32+
- name: Run clippy (linter)
33+
run: cargo clippy --all -- -D warnings
34+
35+
- name: Run fmt (format check)
36+
run: cargo fmt --all -- --check

.github/workflows/rust-stable.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Rust Stable CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build-and-test-stable:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Install system dependencies
15+
run: sudo apt-get update && sudo apt-get install -y libfontconfig1-dev pkg-config
16+
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Set up Rust Stable
21+
uses: dtolnay/rust-toolchain@stable
22+
with:
23+
components: rustfmt, clippy
24+
25+
- name: Build
26+
run: cargo build --verbose
27+
28+
- name: Run tests
29+
run: cargo test --all --verbose
30+
31+
- name: Run clippy (linter)
32+
run: cargo clippy --all -- -D warnings
33+
34+
- name: Run fmt (format check)
35+
run: cargo fmt --all -- --check

.github/workflows/rust.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Rust CI
1+
name: Rust CI (All Versions)
22

33
on:
44
push:
@@ -7,8 +7,11 @@ on:
77
branches: [ main ]
88

99
jobs:
10-
build-and-test:
10+
# This workflow orchestrates all Rust version checks
11+
# Individual version badges can be found in separate workflow files
12+
all-rust-versions:
1113
runs-on: ubuntu-latest
14+
needs: []
1215
strategy:
1316
fail-fast: false
1417
matrix:

CODSPEED_SETUP.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# CodSpeed Integration Setup Guide
2+
3+
## Overview
4+
5+
This document explains how to complete the CodSpeed.io integration for continuous performance monitoring of the `rslife` actuarial library.
6+
7+
## What We've Set Up
8+
9+
**Criterion.rs with CodSpeed compatibility** - Added to `Cargo.toml`
10+
**Comprehensive benchmark suite** - Created 3 benchmark files:
11+
- `benches/commutations.rs` - Commutation functions (Dx, Nx, Mx, Cx, Rx, Sx)
12+
- `benches/mortality_functions.rs` - Basic mortality functions (qx, lx, dx, px)
13+
- `benches/annuities.rs` - Annuity calculations and variations
14+
15+
**GitHub Actions workflow** - `.github/workflows/codspeed.yml`
16+
17+
## Manual Steps Required
18+
19+
### 1. Configure CodSpeed.io Account
20+
21+
1. **Visit CodSpeed.io**
22+
```
23+
https://codspeed.io/
24+
```
25+
26+
2. **Sign up with GitHub**
27+
- Use your GitHub account to sign up
28+
- Grant necessary permissions
29+
30+
3. **Connect your repository**
31+
- Add the `rslife` repository to CodSpeed
32+
- Follow the integration wizard
33+
34+
4. **Generate API token**
35+
- Go to your CodSpeed dashboard
36+
- Navigate to Settings → Tokens
37+
- Generate a new token for `rslife`
38+
39+
### 2. Add GitHub Secret
40+
41+
1. Go to your GitHub repository: `https://github.com/hnlearndev/rslife`
42+
2. Navigate to **Settings****Secrets and variables****Actions**
43+
3. Click **New repository secret**
44+
4. Name: `CODSPEED_TOKEN`
45+
5. Value: Paste the token from CodSpeed.io
46+
6. Click **Add secret**
47+
48+
### 3. Test the Setup
49+
50+
Run benchmarks locally to verify everything works:
51+
52+
```bash
53+
# Install dependencies
54+
cargo build
55+
56+
# Run individual benchmark suites
57+
cargo bench --bench commutations
58+
cargo bench --bench mortality_functions
59+
cargo bench --bench annuities
60+
61+
# Run all benchmarks
62+
cargo bench
63+
```
64+
65+
### 4. Verify CI Integration
66+
67+
1. Create a test branch and make a small change
68+
2. Open a PR to main branch
69+
3. Check that CodSpeed workflow runs successfully
70+
4. Verify CodSpeed comments appear on the PR
71+
72+
## Benchmark Coverage
73+
74+
### Core Mathematical Functions
75+
- **Commutation Functions**: Dx, Nx, Mx, Cx, Rx, Sx with various scenarios
76+
- **Mortality Functions**: qx, lx, dx, px lookups and calculations
77+
- **Life Annuities**: Whole life, temporary, deferred variations
78+
- **Certain Annuities**: Fixed-period calculations
79+
- **Increasing Annuities**: Growing payment streams
80+
81+
### Performance Scenarios
82+
- Single value calculations
83+
- Bulk operations (age ranges)
84+
- 1D vs 2D table operations
85+
- Different mortality tables (AM92, SULT)
86+
- Various interest rates and payment frequencies
87+
- Edge cases (young/old ages)
88+
89+
### Data Loading Benchmarks
90+
- Mortality table loading from different sources
91+
- Configuration setup performance
92+
93+
## Using CodSpeed Results
94+
95+
### Interpreting Results
96+
- **Green indicators**: Performance maintained or improved
97+
- **Red indicators**: Performance regression detected
98+
- **Statistical significance**: CodSpeed uses rigorous statistical analysis
99+
100+
### Performance Monitoring
101+
- Track trends over time in CodSpeed dashboard
102+
- Set up alerts for significant regressions
103+
- Compare performance across different actuarial scenarios
104+
105+
### Optimization Workflow
106+
1. Make code changes
107+
2. Run benchmarks locally: `cargo bench`
108+
3. Check CodSpeed PR comments for performance impact
109+
4. Investigate any regressions before merging
110+
111+
## Maintenance
112+
113+
### Adding New Benchmarks
114+
When adding new actuarial functions:
115+
116+
1. Add benchmark to appropriate file in `benches/`
117+
2. Follow existing patterns for setup and measurement
118+
3. Include realistic scenarios and edge cases
119+
4. Test locally before committing
120+
121+
### Benchmark Best Practices
122+
- Use representative data (real mortality tables)
123+
- Cover common usage patterns
124+
- Include performance-critical code paths
125+
- Avoid I/O operations in benchmark loops
126+
- Use consistent test data across benchmarks
127+
128+
## Troubleshooting
129+
130+
### Common Issues
131+
132+
**Benchmark compilation errors:**
133+
- Check that all imports in benchmark files are correct
134+
- Ensure CodSpeed dependencies are properly added
135+
136+
**CodSpeed workflow failing:**
137+
- Verify `CODSPEED_TOKEN` secret is set correctly
138+
- Check GitHub Actions logs for specific errors
139+
- Ensure network access for mortality table downloads
140+
141+
**Inconsistent results:**
142+
- CodSpeed uses statistical analysis to filter out noise
143+
- Local variations are normal; focus on CI results
144+
- Consistent regressions indicate real performance issues
145+
146+
### Getting Help
147+
- CodSpeed documentation: https://docs.codspeed.io/
148+
- Criterion.rs guide: https://bheisler.github.io/criterion.rs/
149+
- GitHub Issues for this repository
150+
151+
## Benefits for RSLife
152+
153+
### Continuous Performance Monitoring
154+
- Automatic detection of performance regressions
155+
- Historical performance tracking
156+
- Statistical analysis to distinguish real changes from noise
157+
158+
### Actuarial-Specific Value
159+
- **Mathematical Functions**: Monitor computational performance of complex actuarial calculations
160+
- **Data Processing**: Track efficiency of mortality table operations
161+
- **Scalability**: Ensure library performs well with various table sizes and calculation scenarios
162+
163+
### Development Workflow
164+
- Performance feedback on every PR
165+
- Early detection of expensive changes
166+
- Data-driven optimization decisions
167+
168+
## Next Steps
169+
170+
1. Complete CodSpeed account setup
171+
2. Add `CODSPEED_TOKEN` to GitHub secrets
172+
3. Test with a sample PR
173+
4. Monitor performance trends
174+
5. Expand benchmark coverage as needed
175+
176+
For questions about actuarial calculations or benchmark interpretation, refer to the main `README.md` and documentation.

Cargo.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,17 @@ bon = "3.7.2"
2323

2424
[dev-dependencies]
2525
approx = "0.5"
26+
criterion = { version = "0.5", features = ["html_reports"] }
27+
codspeed-criterion-compat = "2.7.2"
28+
29+
[[bench]]
30+
name = "commutations"
31+
harness = false
32+
33+
[[bench]]
34+
name = "mortality_functions"
35+
harness = false
36+
37+
[[bench]]
38+
name = "annuities"
39+
harness = false

0 commit comments

Comments
 (0)