Skip to content

Improve deserialization performance with streaming parser#12

Closed
knutwannheden wants to merge 3 commits into
mainfrom
performance
Closed

Improve deserialization performance with streaming parser#12
knutwannheden wants to merge 3 commits into
mainfrom
performance

Conversation

@knutwannheden
Copy link
Copy Markdown
Contributor

@knutwannheden knutwannheden commented Jan 13, 2026

Optimize JSON-RPC message handling with several performance improvements:

  1. Streaming deserialization using JsonParser and TokenBuffer:

    • Parse JSON-RPC messages with streaming API instead of reading into intermediate Map<String, Object>
    • Defer params/result parsing using TokenBuffer until actual type is needed via convertValue()
    • Primitives for 'result' are read directly without TokenBuffer
  2. LimitedInputStream for zero-copy content reading:

    • Stream content directly from underlying input without copying to intermediate byte array
    • Properly handles remaining bytes after message deserialization
  3. ObjectWriter caching via ClassValue for serialization:

    • Cache ObjectWriter instances per message type for faster writes
  4. ThreadLocal ByteArrayOutputStream for send buffer reuse:

    • Avoid allocating new buffer for each message sent

Refactor JsonRpcSuccess and JsonRpcMethod to use the MessageFormatter
interface instead of their own static ObjectMapper instances. This
removes duplicate ObjectMapper configurations and centralizes JSON
conversion through the MessageFormatter.convertValue() method.

Key changes:
- Add convertValue(Object, Type) method to MessageFormatter interface
- JsonRpc now takes a MessageFormatter parameter (with deprecated
  single-arg constructor for backwards compatibility)
- JsonRpcSuccess uses injected formatter via factory method
- JsonRpcMethod.convertAndHandle() takes formatter parameter

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Optimize JSON-RPC message handling with several performance improvements:

1. Streaming deserialization using JsonParser and TokenBuffer:
   - Parse JSON-RPC messages with streaming API instead of reading
     into intermediate Map<String, Object>
   - Defer params/result parsing using TokenBuffer until actual type
     is needed via convertValue()
   - Primitives for 'result' are read directly without TokenBuffer

2. LimitedInputStream for zero-copy content reading:
   - Stream content directly from underlying input without copying
     to intermediate byte array
   - Properly handles remaining bytes after message deserialization

3. ObjectWriter caching via ClassValue for serialization:
   - Cache ObjectWriter instances per message type for faster writes

4. ThreadLocal ByteArrayOutputStream for send buffer reuse:
   - Avoid allocating new buffer for each message sent
Base automatically changed from write-performance to main January 27, 2026 11:45
Resolved conflicts:
- JsonMessageFormatter: kept streaming parser implementation
- HeaderDelimitedMessageHandler: kept LimitedInputStream and ThreadLocal buffer
  optimizations while preserving effectiveFormatter for backwards compatibility
- JsonRpcTest: use non-deprecated 2-arg HeaderDelimitedMessageHandler constructor

if (method != null) {
return new JsonRpcRequest(id, method, params);
} else if (errorBuffer != null) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else if (errorBuffer != null) {
}
if (errorBuffer != null) {

@jkschneider
Copy link
Copy Markdown
Member

Superseded by #18

@jkschneider jkschneider closed this May 7, 2026
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