perf: buffer native stdout writes#869
Open
He-Pin wants to merge 1 commit into
Open
Conversation
Motivation: Scala Native kube-prometheus rendering still showed write overhead after the renderer/import stack. NativeOutputStream already writes through fwrite, but stdout used the platform default stdio buffer. Modification: Configure NativeOutputStream with full C stdio buffering via setvbuf before rendering, using a 256 KiB buffer size. Result: Native kube-prometheus A/B on the 0.5.12 stack improved in both orders: forward 218.848 ms clean vs 188.528 ms candidate; reverse 183.701 ms candidate vs 224.045 ms clean. Output matched by cmp; clean PR branch reformat, full tests, and bench regressions passed.
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:
Scala Native kube-prometheus rendering still showed write/output overhead after the renderer and strict JSON import stack.
NativeOutputStreamalready bypasses the JVM-compatiblePrintStreampath by writing through Cfwrite, but stdout still used the platform default stdio buffering.Key Design Decision:
Keep this optimization Native-only and local to stdout buffering. Instead of changing renderer flush thresholds or
ByteBuilderbehavior globally, configure the C stdio stream with full buffering before anyNativeOutputStreamwrites occur. Passing a null buffer lets libc own the buffer lifetime, so the Scala object does not need to retain native memory.Modification:
NativeOutputStreamwithsetvbuf(file, null, _IOFBF, 256 KiB)during construction.flush()behavior for trailing newline and close handling.Benchmark Results:
Workload:
jrsonnet/tests/realworld/entry-kube-prometheus.jsonnet -J vendorCandidate was benchmarked on the Scala Native 0.5.12 stacked exploration branch against clean
cf7b8af9.Output equality matched by
cmp.Validation:
./mill --no-server --ticker false --color false __.reformat./mill --no-server --ticker false --color false -j 1 __.test— 444 passed, 0 failed./mill --no-server --ticker false --color false bench.runRegressionsAnalysis:
This is a lower-risk write/flush optimization than increasing
ByteBuilderthresholds: it does not alter rendering order, JSON escaping, object materialization, or JVM/JS behavior. It only changes the buffering policy of the Native stdoutFILE*, and explicit flushes still happen at the same public boundaries.References:
Result:
Native stdout rendering writes fewer/smoother buffered chunks for large JSON output while preserving byte-identical output and the existing flush contract.