[
https://issues.apache.org/jira/browse/TAP5-2837?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ben Weidig reassigned TAP5-2837:
--------------------------------
Assignee: Ben Weidig
> Improve JSON serialization performance (toString/toCompactString)
> -----------------------------------------------------------------
>
> Key: TAP5-2837
> URL: https://issues.apache.org/jira/browse/TAP5-2837
> Project: Tapestry 5
> Issue Type: Improvement
> Components: tapestry-json
> Affects Versions: 5.10.0
> Reporter: Ben Weidig
> Assignee: Ben Weidig
> Priority: Minor
>
> h3. Overview
> {{JSONObject}}/{{JSONArray}}'s {{toString()}} and {{toCompactString()}} are
> slower than necessary due to synchronization overhead and per-{{String}}
> allocation in the print path.
> My sandbox implementation at
> https://github.com/benweidig/tapestry-json-improvements (non-breaking,
> verified byte-for-byte against current output) shows a ~4-6x speedup across
> payload sizes and both compact/pretty formatting, with no public API changes.
> h3. Problem
> * {{toString()}}/{{toCompactString()}} route output through
> {{CharArrayWriter}} wrapped in {{PrintWriter}}, both use {{synchronized}}
> methods on every write. This is pure overhead for single-threaded string
> building.
> * {{JSONObject.quote(String)}} allocates a new {{JSONStringer}} (own
> {{StringBuilder}} + {{ArrayList}} scope stack) for every quoted string, like
> keys and string values in a payload.
> * Extended-Unicode escaping goes through {{String.format}}, which parses the
> format string on every call.
> * Output buffers start at JDK default capacity with no pre-sizing, causing
> repeated grow/copy for larger trees.
> h3. Proposed changes
> Delete {{JSONStringer}} and inline its escaping loop directly into
> {{JSONObject}} as a static {{escapeInto(...)}} helper, called directly by
> {{quote()}} and the print sessions.
> Replace {{String.format}} hex escaping with manual nibble extraction + lookup
> table.
> Drop {{CharArrayWriter}}/{{PrintWriter}} for
> {{toString()}}/{{toCompactString()}}.
> Instead, build directly into a {{StringBuilder}}.
> Pre-size the output buffer based on collection size instead of the JDK
> default.
> All changes are additive/internal/package-private only, without any no
> signature changes, no behavior changes.
> Full test suite plus a new baseline-equivalence test confirmed identical
> output to 5.9.1 in my sandbox.
> h3. Risks
> * Low functional risk: escaping logic is a straight extraction/refactor,
> covered by existing tests.
> * Removing {{JSONStringer}} is a *breaking change* for any external caller
> referencing that class directly (it's currently public): Needs a
> compatibility/deprecation decision before merge.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)