Fuse restInHandler into GraphStageLogic in Intersperse#2981
Open
He-Pin wants to merge 3 commits into
Open
Conversation
Optimize several stream stages by fusing separate InHandler/OutHandler objects into the GraphStageLogic itself, reducing per-materialization memory allocations: 1. DoOnFirst: Replace separate InHandler with boolean flag pattern 2. Intersperse: Merge two InHandler objects (start/rest) into single fused handler 3. Reduce: Eliminate initial InHandler by using hasFirst flag 4. DropWithin: Replace post-timeout InHandler with timedOut flag 5. Scan: Remove initial InHandler/OutHandler pair using initialized flag 6. ScanAsync: Remove ZeroHandler and post-completion OutHandler Tests: - stream-tests/testOnly FlowDoOnFirstSpec: 2/2 passed - stream-tests/testOnly FlowIntersperseSpec: 8/8 passed - stream-tests/testOnly FlowReduceSpec: 12/12 passed - stream-tests/testOnly FlowDropWithinSpec: 2/2 passed - stream-tests/testOnly FlowScanSpec: 8/8 passed - stream-tests/testOnly FlowScanAsyncSpec: 19/19 passed
…cations" This reverts commit f9f0370.
Optimize Intersperse stage by fusing the hot-path restInHandler into GraphStageLogic itself, reducing per-materialization object allocation. Before: GraphStageLogic with OutHandler + startInHandler + restInHandler After: GraphStageLogic with InHandler with OutHandler + startInHandler The cold-path startInHandler (only used once for first element) remains as a separate object. The hot-path restInHandler logic is now directly in the fused GraphStageLogic, eliminating one InHandler allocation per materialization without adding any boolean checks on the hot path. Tests: - stream-tests/testOnly FlowIntersperseSpec: 8/8 passed
Contributor
There was a problem hiding this comment.
Pull request overview
This PR optimizes the Intersperse stream stage implementation by fusing the hot-path restInHandler into the GraphStageLogic instance, reducing per-materialization allocations while preserving the existing cold-path handler switch for the first element.
Changes:
- Refactors
Intersperse#createLogicto have theGraphStageLogicdirectly implementInHandlerfor the steady-state (hot) path. - Keeps a dedicated
startInHandlerfor the first-element (cold) path, then switches the inlet handler to the fused logic instance.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Optimize Intersperse stage by fusing the hot-path
restInHandlerinto GraphStageLogic, reducing per-materialization object allocation.Modification
Before:
After:
Result
InHandlerallocation per materialization on the hot pathstartInHandlerremains as separate object (only used once)Tests
stream-tests/testOnly FlowIntersperseSpec: 8/8 passed