Skip to content

Commit bcf9adf

Browse files
Korijnclaude
andauthored
Filter plain leaf values out of the traverse stack at push time (#190)
Every scalar leaf used to be pushed onto the traversal stack as a (value, tracked) tuple, only to be popped, run through the Proxy isinstance check and the type dispatch, and discarded. Filtering plain-typed values (which can never be a proxy or a traversable container) at push time skips all of that. Measured on bench/test_traverse.py: test_traverse_matrix 374us -> 83us, test_traverse_large_flat_list 134us -> 22us, test_traverse_mixed 38us -> 18us, test_traverse_shallow 14us -> 3us. Claude-Session: https://claude.ai/code/session_01UyALuqgF1ZZ3Lj88FzwGVc Co-authored-by: Claude <noreply@anthropic.com>
1 parent 1889213 commit bcf9adf

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

observ/watcher.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from weakref import ref
1717

1818
from .dep import Dep
19-
from .proxy import Proxy, proxy
19+
from .proxy import PLAIN_TYPES, Proxy, proxy
2020
from .proxy_db import proxy_db
2121
from .scheduler import scheduler
2222

@@ -218,9 +218,16 @@ def traverse(obj: Any) -> None:
218218
dep = proxy(current).__dep__
219219
dep.depend()
220220

221-
# Add children to stack
221+
# Add children to stack. Plain-typed values are filtered out
222+
# right here: they can never be a proxy or a traversable
223+
# container, so pushing them just to discard them on the next
224+
# pop would double the cost of scalar-heavy containers
222225
if current:
223-
stack.extend((value, child_tracked) for value in val_iter)
226+
stack.extend(
227+
(value, child_tracked)
228+
for value in val_iter
229+
if type(value) not in PLAIN_TYPES
230+
)
224231

225232

226233
# Every Watcher gets a unique ID which is used to

0 commit comments

Comments
 (0)