docs: refresh README and CLAUDE.md; add ingest benchmark
The CLAUDE.md architecture section still described the pre-redesign engine: its data flow named `Batch`, `Agent`, `Player` and `message.rs`, none of which have existed since T2, and the public API it listed did not match `lib.rs`. It is the first thing a fresh session reads, so it was actively misleading. Rewritten against the current module layout, with the invariants that are easy to violate — ties needing a positive `p_draw`, NaN never being convergence, log-space evidence, color contiguity, `forbid(unsafe_code)`, and ingestion-order equivalence — written down. The README Todo list had five entries that were already done, including "Time needs to be an enum": `Time` has been a trait since T2, and the `batch::compute_elapsed()` it pointed at no longer exists. The genuinely open item — cross-checking `quality()` against sublee/trueskill — stays. `benches/ingest.rs` measures one-event-per-call against a single batched call. The rest of the suite only measured batched construction, which is why the quadratic fixed earlier on this branch went unnoticed for so long. `TimeSlice::log_evidence` also hashes its target set once instead of scanning the slice per player per event, so `log_evidence_for` with many keys is no longer quadratic. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnsaJg74eNSva3PJjK2eej
This commit is contained in:
+5
-2
@@ -587,6 +587,9 @@ impl<T: Time> TimeSlice<T> {
|
||||
forward: bool,
|
||||
agents: &CompetitorStore<T, D>,
|
||||
) -> f64 {
|
||||
// Hashed once rather than scanned per player per event, so a
|
||||
// `log_evidence_for` with many keys is not quadratic.
|
||||
let target_set: std::collections::HashSet<Index> = targets.iter().copied().collect();
|
||||
// log_evidence is infrequent; a local arena avoids needing &mut self.
|
||||
let mut arena = ScratchArena::new();
|
||||
|
||||
@@ -636,7 +639,7 @@ impl<T: Time> TimeSlice<T> {
|
||||
.teams
|
||||
.iter()
|
||||
.flat_map(|team| &team.items)
|
||||
.any(|item| targets.contains(&item.agent))
|
||||
.any(|item| target_set.contains(&item.agent))
|
||||
})
|
||||
.map(|event| run_event(event, &mut arena))
|
||||
.sum()
|
||||
@@ -648,7 +651,7 @@ impl<T: Time> TimeSlice<T> {
|
||||
.teams
|
||||
.iter()
|
||||
.flat_map(|team| &team.items)
|
||||
.any(|item| targets.contains(&item.agent))
|
||||
.any(|item| target_set.contains(&item.agent))
|
||||
})
|
||||
.map(|event| event.log_evidence)
|
||||
.sum()
|
||||
|
||||
Reference in New Issue
Block a user