Skip to content

Commit 02118bf

Browse files
committed
perf: bound header buffers and reuse builders in StreamMessageProducer
Replace nullable builders with reusable instances to reduce allocations during header scan; avoid repeated StringBuilder creation.
1 parent 79e2cf7 commit 02118bf

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

org.eclipse.lsp4j.jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/StreamMessageProducer.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ public void listen(MessageConsumer callback) {
7474
this.keepRunning = true;
7575
this.callback = callback;
7676
try {
77-
StringBuilder headerBuilder = null;
78-
StringBuilder debugBuilder = null;
77+
final var headerBuilder = new StringBuilder();
78+
final var debugBuilder = new StringBuilder();
7979
boolean newLine = false;
8080
Headers headers = new Headers();
8181
while (keepRunning) {
@@ -84,8 +84,6 @@ public void listen(MessageConsumer callback) {
8484
// End of input stream has been reached
8585
keepRunning = false;
8686
} else {
87-
if (debugBuilder == null)
88-
debugBuilder = new StringBuilder();
8987
debugBuilder.append((char) c);
9088
if (c == '\n') {
9189
if (newLine) {
@@ -100,17 +98,15 @@ public void listen(MessageConsumer callback) {
10098
newLine = false;
10199
}
102100
headers = new Headers();
103-
debugBuilder = null;
104-
} else if (headerBuilder != null) {
101+
resetStringBuilder(debugBuilder);
102+
} else if (headerBuilder.length() > 0) {
105103
// A single newline ends a header line
106104
parseHeader(headerBuilder.toString(), headers);
107-
headerBuilder = null;
105+
resetStringBuilder(headerBuilder);
108106
}
109107
newLine = true;
110108
} else if (c != '\r') {
111109
// Add the input to the current header line
112-
if (headerBuilder == null)
113-
headerBuilder = new StringBuilder();
114110
headerBuilder.append((char) c);
115111
newLine = false;
116112
}
@@ -129,6 +125,17 @@ public void listen(MessageConsumer callback) {
129125
}
130126
}
131127

128+
private void resetStringBuilder(final StringBuilder sb) {
129+
// If the builder grew large, shrink its backing byte array to an upper bound
130+
if (sb.length() > 8192) {
131+
// Truncate so trimToSize() can reduce the internal capacity.
132+
sb.setLength(8192);
133+
sb.trimToSize();
134+
}
135+
// Clear content while keeping the (now trimmed) capacity for reuse.
136+
sb.setLength(0);
137+
}
138+
132139
/**
133140
* Log an error.
134141
*/

0 commit comments

Comments
 (0)