mirror of https://github.com/icsharpcode/ILSpy.git
Browse Source
A node's children carry a cached flattened childIndex, rebuilt by EnsureChildIndices after any structural mutation invalidates it. The single-slot setter and the collection indexer invalidated the whole set on every in-place replace, so the next sibling navigation (e.g. the visitor's NextSibling walk) rebuilt all indices in O(children). A transform that replaces each element of a block while traversing it was therefore O(N^2). But replacing a child in place does not move anything: a single slot always occupies the same flattened index, and a replaced collection element keeps its position. So carry the old child's index to the new child and skip the invalidation. Setting or clearing a slot still invalidates, since the new child's index is not known locally; a stale carried value is corrected by the next renumber anyway. Microbenchmark (replace every statement in an N-statement block): at N=32000, 2158 ms -> 1 ms. Output is byte-identical and the Pretty suite stays green with CheckInvariant active. Assisted-by: Claude:claude-opus-4-8:Claude Codepull/3807/head
2 changed files with 17 additions and 3 deletions
Loading…
Reference in new issue