Skip to content

perf: appendString bulk array copy via String.getChars#681

Open
He-Pin wants to merge 1 commit intodatabricks:masterfrom
He-Pin:perf/renderer-bulk-append
Open

perf: appendString bulk array copy via String.getChars#681
He-Pin wants to merge 1 commit intodatabricks:masterfrom
He-Pin:perf/renderer-bulk-append

Conversation

@He-Pin
Copy link
Copy Markdown
Contributor

@He-Pin He-Pin commented Apr 5, 2026

Motivation

The renderer's appendString method copies string characters one-by-one in a loop. For large strings (common in JSON rendering), this is slower than bulk array copy.

Key Design Decision

Replace the character-by-character copy loop with String.getChars() which uses optimized System.arraycopy() internally for bulk memory transfer.

Modification

  • Renderer: Changed appendString from per-char loop to String.getChars() bulk copy (6 lines changed)

Benchmark Results

JMH (JVM, 3 iterations)

Benchmark Master (ms/op) This PR (ms/op) Change
bench.02 50.427 ± 38.906 46.057 ± 4.798 -8.7%
comparison2 85.854 ± 188.657 70.018 ± 27.809 -18.4% 🔥
realistic2 73.458 ± 66.747 66.273 ± 6.833 -9.8%

Analysis

  • Consistent -9% to -18% improvement across all key benchmarks
  • String.getChars() uses System.arraycopy() internally — SIMD-optimized on modern JVMs
  • Particularly effective for rendering-heavy workloads that output large JSON
  • No regressions

References

  • Upstream exploration: he-pin/sjsonnet jit branch commit 5e9686cd

Result

-9% to -18% JVM improvement by replacing per-char string copy with bulk array copy.

@He-Pin He-Pin marked this pull request as ready for review April 5, 2026 02:07
@stephenamar-db
Copy link
Copy Markdown
Collaborator

CI check found a scalafmt formatting violation in sjsonnet/src/sjsonnet/BaseCharRenderer.scala. Tests pass. Please run ./mill __.reformat and push the fix.

@He-Pin He-Pin force-pushed the perf/renderer-bulk-append branch 3 times, most recently from 0a187be to 8834d96 Compare April 9, 2026 00:56
Replace char-by-char appendUnsafeC loop with String.getChars bulk copy
directly into CharBuilder's backing array. This eliminates per-character
method call overhead and allows the JVM/native runtime to use optimized
memory copy intrinsics.

Upstream: 5e9686cd (appendString portion)
@He-Pin He-Pin force-pushed the perf/renderer-bulk-append branch from 8834d96 to 5655ff2 Compare April 9, 2026 03:02
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.

2 participants