Commit ·
4c1cadb
1
Parent(s): 7c57667
Lazy neighbor cleanup: remove O(N) scan from every free
Browse filesEager neighbor list cleanup on remove_region() was O(N × avg_neighbors)
per free — killed throughput from 1.47M/s to 48K/s. Stale neighbor
references are harmless (step() already checks regions.contains_key).
Batch cleanup deferred to prune_stale_neighbors() during sleep.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- rust_core/src/lenia.rs +14 -4
rust_core/src/lenia.rs
CHANGED
|
@@ -185,8 +185,11 @@ impl LeniaField {
|
|
| 185 |
}
|
| 186 |
|
| 187 |
/// Remove a region from the field — called when an allocation is freed.
|
| 188 |
-
/// Reclaims the energy and removes from
|
| 189 |
-
///
|
|
|
|
|
|
|
|
|
|
| 190 |
pub fn remove_region(&mut self, id: u32) {
|
| 191 |
if let Some(region) = self.regions.remove(&id) {
|
| 192 |
let energy = region.temperature * (region.size_bytes as f64 / (1024.0 * 1024.0));
|
|
@@ -196,9 +199,16 @@ impl LeniaField {
|
|
| 196 |
}
|
| 197 |
}
|
| 198 |
self.neighbors.remove(&id);
|
| 199 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
for (_rid, nbrs) in self.neighbors.iter_mut() {
|
| 201 |
-
nbrs.retain(|(nid, _)|
|
| 202 |
}
|
| 203 |
}
|
| 204 |
|
|
|
|
| 185 |
}
|
| 186 |
|
| 187 |
/// Remove a region from the field — called when an allocation is freed.
|
| 188 |
+
/// Reclaims the energy and removes from primary tracking.
|
| 189 |
+
/// Stale neighbor references are left in place — step() already handles
|
| 190 |
+
/// missing regions gracefully (skips them). Eager neighbor cleanup was
|
| 191 |
+
/// O(N × avg_neighbors) on every free, which killed throughput.
|
| 192 |
+
/// Sleep consolidation prunes stale references in batch.
|
| 193 |
pub fn remove_region(&mut self, id: u32) {
|
| 194 |
if let Some(region) = self.regions.remove(&id) {
|
| 195 |
let energy = region.temperature * (region.size_bytes as f64 / (1024.0 * 1024.0));
|
|
|
|
| 199 |
}
|
| 200 |
}
|
| 201 |
self.neighbors.remove(&id);
|
| 202 |
+
// Stale references in OTHER regions' neighbor lists are harmless —
|
| 203 |
+
// step() checks regions.contains_key() before using a neighbor.
|
| 204 |
+
// Batch cleanup happens during sleep consolidation.
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
/// Prune stale neighbor references — call during sleep consolidation.
|
| 208 |
+
/// Removes references to regions that no longer exist.
|
| 209 |
+
pub fn prune_stale_neighbors(&mut self) {
|
| 210 |
for (_rid, nbrs) in self.neighbors.iter_mut() {
|
| 211 |
+
nbrs.retain(|(nid, _)| self.regions.contains_key(nid));
|
| 212 |
}
|
| 213 |
}
|
| 214 |
|