[Java] Avoid RowCoder bytecode generation - #39619
Open
bvolpato wants to merge 1 commit into
Open
Conversation
bvolpato
marked this pull request as ready for review
August 5, 2026 00:04
Contributor
|
Assigning reviewers: R: @Abacn for label java. Note: If you would like to opt out of this review, comment Available commands:
The PR bot will only process comments in the main thread (not review comments). |
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.
RowCoderGeneratorcurrently creates and loads one ByteBuddy class for every uncached schema. Generatedencodeanddecodemethods only load instance fields and call existing Java delegates, so class generation adds startup time, allocation, metaspace pressure, and class-loader complexity without specializing field encoding.This replaces generated classes with one immutable
CustomCoder<Row>implementation while preserving schema UUID caching, encoding-position overrides, component coders, and existing encode/decode algorithms. It also adds JMH coverage for uncached coder creation and steady-state encoding/decoding.Benchmarks
JDK 17, same host, three isolated JVM forks. Generation includes schema construction;
buildSchemais a control.masterCommand:
./gradlew :sdks:java:core:jmh:jmh --args='org.apache.beam.sdk.jmh.coders.RowCoderGenerationBenchmark -prof gc -f 3 -foe=true'Steady-state results use identical benchmarks and three forks:
masterns/opAll old/new confidence intervals overlap, showing no material steady-state regression.
Historical context
RowCoder generation was introduced in 2018 to replace an implementation that inspected the schema and rebuilt component coders while processing every row. The combined change was reported as 30-40% faster. That comparison was against the former introspecting implementation, not against an ordinary coder with the same precomputed fields used here.
Over time, component-coder construction moved into regular Java and the resulting array was passed into the generated class. Its encode and decode methods remained forwarding wrappers around shared loops. Precomputing field coders is still valuable and remains unchanged in this PR; generating a class no longer provides that benefit. Current benchmarks show equivalent steady-state performance, while class generation adds substantial creation time and allocation.
Wire compatibility and testing
Encoding and decoding algorithms are unchanged. Java passes Beam's exact standard-coder vectors, including
beam:coder:row:v1vectors produced by Python../gradlew :runners:java-fn-execution:test --tests org.apache.beam.runners.fnexecution.wire.CommonCoderTest(227 passed)./gradlew :sdks:java:core:test(full core suite passed;RowCoderTest28/28 andSchemaCoderTest19/19)./gradlew :sdks:java:core:spotlessApply :sdks:java:core:jmh:spotlessApplyRowCoderBenchmarkJMH runs for dynamic and static encodingsCHANGES.mdentry; internal performance change with unchanged API and wire format.