From 3749678de3907a7485169a052ac83fe17c62216a Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Mon, 29 Jun 2020 07:54:48 -0700 Subject: [PATCH] Use fixed size buffer in ReadJsonFromInputStream It is inefficient to be constantly allocating and filling an ArrayBuffer. The buffer is only used for reading headers that we mostly discard anyway. My assumption is that since we only care about content length, it's fine to put a fixed limit on the buffer size. --- .../util/ReadJsonFromInputStream.scala | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/main-command/src/main/scala/sbt/internal/util/ReadJsonFromInputStream.scala b/main-command/src/main/scala/sbt/internal/util/ReadJsonFromInputStream.scala index faf63f7e4..fa9dd7862 100644 --- a/main-command/src/main/scala/sbt/internal/util/ReadJsonFromInputStream.scala +++ b/main-command/src/main/scala/sbt/internal/util/ReadJsonFromInputStream.scala @@ -10,7 +10,6 @@ package sbt.internal.util import java.io.InputStream import java.nio.channels.ClosedChannelException import java.util.concurrent.atomic.AtomicBoolean -import scala.collection.mutable import scala.util.Try private[sbt] object ReadJsonFromInputStream { @@ -22,10 +21,19 @@ private[sbt] object ReadJsonFromInputStream { val newline = '\n'.toInt val carriageReturn = '\r'.toInt val contentLength = "Content-Length: " - var bytes = new mutable.ArrayBuffer[Byte] + var index = 0 + /* + * This is the buffer into which we copy headers. The value of 128 bytes is + * somewhat arbitrary but chosen to ensure that there is enough space + * for any reasonable header. Any header exceeding 128 bytes will + * be truncated. The only header we care about at the moment is + * content-length, so this should be fine. If we ever start doing anything + * with headers, we may need to adjust this buffer size. + */ + val headerBuffer = new Array[Byte](128) def getLine(): String = { - val line = new String(bytes.toArray, "UTF-8") - bytes = new mutable.ArrayBuffer[Byte] + val line = new String(headerBuffer, 0, index, "UTF-8") + index = 0 onHeader.foreach(oh => oh(line)) line } @@ -51,7 +59,10 @@ private[sbt] object ReadJsonFromInputStream { case `carriageReturn` => onCarriageReturn = true case c => if (c == newline) getLine() - else bytes += c.toByte + else { + if (index < headerBuffer.length) headerBuffer(index) = c.toByte + index += 1 + } onCarriageReturn = false consecutiveLineEndings = 0 } @@ -74,7 +85,8 @@ private[sbt] object ReadJsonFromInputStream { case `carriageReturn` => onCarriageReturn = true case c => onCarriageReturn = false - bytes += c.toByte + if (index < headerBuffer.length) headerBuffer(index) = c.toByte + index += 1 } } while (content.isEmpty && running.get)