Skip to content

Forward component blocks directly during recursive graph traversal - #35

Open
OskarEichler wants to merge 1 commit into
ruby:masterfrom
OskarEichler:codex/forward-tsort-component-block
Open

Forward component blocks directly during recursive graph traversal#35
OskarEichler wants to merge 1 commit into
ruby:masterfrom
OskarEichler:codex/forward-tsort-component-block

Conversation

@OskarEichler

Copy link
Copy Markdown

Summary

Forward the component callback directly through the recursive traversal instead of wrapping it in a new block at every level. This removes wrapper allocations and repeated callback relays while preserving component ordering and cycle semantics.

Measurement and verification

On macOS/Ruby 4.0.6 through rbenv, seven samples of 50 sorts of a 300-node chain:

  • Median allocations: 90,600 → 60,600.
  • Median elapsed time: 0.034855s → 0.007224s.

These are local microbenchmark results, not a claim about every graph or Rails startup. The improvement removes the nested callback relay as each component is emitted.

  • Existing suite: 8 tests / 17 assertions, no failures before or after.
  • 4,000 external checks on 1,000 deterministic graphs: independently checked component membership using mutual reachability, component ordering, existing cycle behavior, and early block exits. All component and sort results are byte-for-byte identical before/after.
  • A backport based on installed 0.2.0 passes the same suite and graph checks.
  • Ruby syntax, gem build and git diff --check pass. The release-based package retains 11 files, Ruby >=2.3.0 and no runtime dependencies/extensions.

No tests were added or changed under the requesting project's explicit policy. The graph checker and benchmark are external scratch scripts. Other Ruby versions and OSs were not run locally.

Breaking changes and limitations

None intended. Callback order, yielded values, self-loop treatment and multi-node cycle errors are preserved. In particular, this does not change the behavior discussed in #4. The traversal itself remains recursive; this is not a stack-safe rewrite for arbitrarily deep graphs. Reflection now exposes a named block parameter on the two internal traversal entry points.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant