Skip to content

Add Stream type-pollution benchmark and guidance#3333

Open
He-Pin wants to merge 1 commit into
apache:mainfrom
He-Pin:perf/1668-stream-type-pollution
Open

Add Stream type-pollution benchmark and guidance#3333
He-Pin wants to merge 1 commit into
apache:mainfrom
He-Pin:perf/1668-stream-type-pollution

Conversation

@He-Pin

@He-Pin He-Pin commented Jul 11, 2026

Copy link
Copy Markdown
Member

Motivation

JDKs affected by JDK-8180450 can lose multi-core scalability when the same concrete class is checked against alternating secondary supertypes. In Pekko Streams, this can happen in non-inlined user operator functions whose erased bridges cast the same elements to different interfaces.

The original issue analysis also suspected the fused Connection.slot: Any and generic grab[T] path. Bytecode inspection and focused type-pollution-agent runs did not find pollution in GraphInterpreter or GraphStageLogic; the observed updates came from the user-function bridge casts. Changing the interpreter representation would therefore add hot-path risk without addressing the measured cause.

Modification

  • Add a fused-stream JMH benchmark comparing concrete, stable-interface, and alternating-interface operator chains.
  • Prevent benchmark function inlining so the interface bridge casts and affected-JDK contention remain reproducible.
  • Add a directional Flow.map test for the alternating-interface chain.
  • Document the precise trigger, fixed JDK versions, mitigations, and profiling guidance.

Result

The benchmark reproduces the scalability loss on JDK 17.0.17 and verifies its removal in JDK 21.0.8. Scores are elements per microsecond with 12 JMH threads, 3 forks, and a six-map fused chain:

JDK Concrete Stable interface Alternating interfaces
17.0.17 74.439 ± 4.051 70.499 ± 4.353 34.813 ± 0.781
21.0.8 67.053 ± 5.019 66.622 ± 6.705 66.412 ± 5.336

On JDK 17, alternating interfaces are about 50.6% slower than the stable-interface control. On JDK 21.0.8, the difference is within 0.4%.

The agent recorded roughly 12.1-12.4 million secondary-supertype cache changes per payload class at the benchmark ToRight / ToLeft bridge casts. Narrowed runs targeting GraphInterpreter and GraphStageLogic reported no type-pollution sites, so this PR intentionally makes no core interpreter hot-path change.

Tests

  • sbt "stream-tests / Test / testOnly org.apache.pekko.stream.scaladsl.FlowMapSpec" — passed, 3 tests
  • sbt "bench-jmh / Jmh / compile" — passed
  • JMH on Temurin 17.0.17 and Temurin 21.0.8 — completed; results above
  • javap -c — verified Left / Right bridge checkcast instructions
  • sbt docs/paradox — passed
  • sbt "+headerCheckAll" checkCodeStyle — passed
  • sbt validatePullRequest — all Stream tests passed; docs validation hit the pre-existing jdocs.stream.IntegrationDocTest reference to pekko.dispatch.UnboundedMailbox already present on origin/main
  • git diff --check — passed
  • Qoder stdout review — No must-fix findings

References

Refs #1668

Motivation:
Affected JDKs can lose throughput when the same stream element crosses alternating interface-typed non-inlined operators. The initial issue analysis attributed this to the fused Connection slot without runtime evidence.

Modification:
Add a fused-stream JMH comparison for concrete, stable-interface, and alternating-interface chains. Add a directional Flow map test and document the verified JVM upgrade and profiling guidance.

Result:
The benchmark reproduces the issue on JDK 17 while showing that JDK 21.0.8 removes the penalty, avoiding an unnecessary change to the core Stream interpreter hot path.

Tests:
- stream-tests / Test / testOnly org.apache.pekko.stream.scaladsl.FlowMapSpec
- bench-jmh / Jmh / compile
- docs/paradox
- +headerCheckAll
- checkCodeStyle
- validatePullRequest (Stream tests passed; pre-existing jdocs.stream.IntegrationDocTest mailbox class-name failure)
- JMH on JDK 17.0.17 and JDK 21.0.8
- Qoder review: No must-fix findings

References:
Refs apache#1668
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