`K` is the one type parameter people change, and it was last. Naming a
history in a struct field meant writing all four to say one thing:
struct Ladder { history: History<i64, ConstantDrift, NullObserver, String> }
struct Analysis<'h> { joint: Joint<'h, i64, ConstantDrift, NullObserver, &'static str> }
Now:
struct Ladder { history: History<String> }
struct Analysis<'h> { joint: Joint<'h> }
`History<K, T, D, O>`, all four defaulted. Bounds may reference later
parameters, so `D: Drift<T> = ConstantDrift` is legal in third position.
`Joint` gains the same defaults, so `Joint<'h, String>` spells it.
72 call sites swapped, and the reorder makes most of them shorter: 18
now read `History<String>` and the `&'static str` ones read `History`.
The two turbofished builders shrink from
`HistoryBuilder::<Untimed, _, _, String>::new()` to
`HistoryBuilder::<String, Untimed>::new()`.
`Joint` keeps `O` structurally, defaulted rather than removed. #72 notes
it never touches the observer, which is true — but it borrows the whole
`&'h History<K, T, D, O>` and calls `History::resolve_terms`, so dropping
the parameter means either a view type or moving that method off
`History`. The default already buys the entire user-visible benefit,
which was the spelling.
Refs #72.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hcFjNDmHXZF8URGLku5zZ
40 lines
1.4 KiB
Rust
40 lines
1.4 KiB
Rust
use criterion::{Criterion, criterion_group, criterion_main};
|
|
use smallvec::smallvec;
|
|
use trueskill_tt::{ConstantDrift, Event, History, Member, Outcome, Team};
|
|
|
|
fn bench_scored_history(c: &mut Criterion) {
|
|
c.bench_function("scored_history_60_events_30_iter", |bencher| {
|
|
bencher.iter(|| {
|
|
let mut h: History<String> = History::builder()
|
|
.key_type::<String>()
|
|
.mu(25.0)
|
|
.sigma(25.0 / 3.0)
|
|
.beta(25.0 / 6.0)
|
|
.drift(ConstantDrift::new(0.03))
|
|
.score_sigma(2.0)
|
|
.build();
|
|
|
|
let mut events: Vec<Event<i64, String>> = Vec::with_capacity(60);
|
|
for i in 0..60 {
|
|
let a = format!("p{}", i % 20);
|
|
let b = format!("p{}", (i + 7) % 20);
|
|
let s_a = (i as f64 * 0.3).sin().abs() * 21.0;
|
|
let s_b = (i as f64 * 0.3).cos().abs() * 21.0;
|
|
events.push(Event {
|
|
time: 1 + (i / 6) as i64,
|
|
teams: smallvec![
|
|
Team::with_members([Member::new(a)]),
|
|
Team::with_members([Member::new(b)]),
|
|
],
|
|
outcome: Outcome::scores([s_a, s_b]),
|
|
});
|
|
}
|
|
h.add_events(events).unwrap();
|
|
let _ = h.converge().unwrap();
|
|
});
|
|
});
|
|
}
|
|
|
|
criterion_group!(benches, bench_scored_history);
|
|
criterion_main!(benches);
|