Skip to content

Commit 6b58645

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 4b6d14b commit 6b58645

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,19 +98,17 @@ public void listen(MessageConsumer callback) {
10098
newLine = false;
10199
}
102100
headers = new Headers();
103-
debugBuilder = null;
101+
resetStringBuilder(debugBuilder);
104102
} else {
105-
if (headerBuilder != null) {
103+
if (headerBuilder.length() > 0) {
106104
// A single newline ends a header line
107105
parseHeader(headerBuilder.toString(), headers);
108-
headerBuilder = null;
106+
resetStringBuilder(headerBuilder);
109107
}
110108
newLine = true;
111109
}
112110
} else if (c != '\r') {
113111
// Add the input to the current header line
114-
if (headerBuilder == null)
115-
headerBuilder = new StringBuilder();
116112
headerBuilder.append((char) c);
117113
newLine = false;
118114
}
@@ -131,6 +127,17 @@ public void listen(MessageConsumer callback) {
131127
}
132128
}
133129

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

0 commit comments

Comments
 (0)