pjfanning opened a new pull request, #1331:
URL: https://github.com/apache/poi/pull/1331

   Item 5 of the evaluator performance list. **Measured effect is marginal — 
see the numbers before deciding whether it earns its place.**
   
   ### What it does
   
   `CellCacheEntry.recurseClearCachedFormulaResults` (the walk behind 
`notifyUpdateCell`) called `getConsumingCells()` at every node, copying the 
consumer set to an array, because each consumer's `clearFormulaEntry()` removes 
it from the set being iterated. The walk now drains the set instead: 
`FormulaCellCacheEntrySet.peekAny()` returns some entry, clearing it removes 
it, repeat until the set is empty. A scan cursor carries on from where the last 
entry was found, so draining stays linear despite the holes removals leave in 
the open-addressing array (and survives the shrink re-hash). `containsPeeked` 
is an O(1) guard that turns a broken invariant (a consumer that does not list 
this cell as an input) into an `IllegalStateException` instead of an endless 
loop. The listener variant of the walk (test/debug only) keeps the array 
because `sortDependentCachedValues` needs one.
   
   A consumer already cleared by a deeper recursion has left the set by the 
time the loop would reach it, so it is skipped rather than cleared a second 
time — same end state as before.
   
   ### Numbers
   
   `HSSFFormulaReevaluationBenchmark` (`-Pjmh.profilers=gc`), clean iterations 
(both runs have GC-boundary outliers):
   
   | rows | alloc/op trunk | alloc/op this | time |
   |---|---|---|---|
   | 100 | 308.5–308.8 KB | 307.1–307.3 KB | ~1.04 ms, unchanged |
   | 200 | 613–615 KB | 611–613 KB | ~1.8 ms, unchanged |
   
   About 0.5% less allocation, no measurable time difference. The copy is one 
small array per invalidated node and the `clearFormulaEntry` work at that node 
(unregistering from every input) dominates it. It would matter more for a cell 
with thousands of consumers, but even there it is one array per notification.
   
   ### Tests
   - `TestFormulaCellCacheEntrySet` (new): add/remove/duplicate, draining 1000 
entries through the grow and shrink re-hashes with `peekAny`/`containsPeeked`, 
`peekAny` not removing.
   - `TestCellCacheEntry`: invalidation walk over a diamond with a 
self-consuming (circular) formula clears every dependent and every 
registration; 500 consumers of one cell.
   - Formula suites green.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to