如何有效地读取 Java(在 Scala 中使用 Java lib)InputStream?

How to reading Java (Using Java lib in Scala) InputStream efficiently?

我的 Scala 服务器通过 socket.getInputStream 从套接字获取 InputStream 对象(从我的套接字客户端发送的一些字节,字节大小打印在下面)

下面的代码尝试将其读取到数组

  var buffer: Array[Byte] = null
  def read(stream: InputStream, size: Int) = {
    val start = System.nanoTime()
    buffer = new Array[Byte](size)
    var value: Int = 0
    (0 until size).foreach(i => {
      value = stream.read()
      buffer(i) = value.toByte
    })
    val end = System.nanoTime()
    println(s"Getting buffer from InputStream, size: $size, cost: ${(end - start)/1e6} ms")
    buffer
  }

部分输出为

Getting buffer from InputStream, size: 4, cost: 174.923596 ms
Getting buffer from InputStream, size: 2408728, cost: 919.207885 ms

然而,对于相同的数据大小,一些现有的服务器可能会更快,例如Redis 可以在 ~10ms 内发送字节,所以

是否可以提高此程序的性能?

stream.read() 是对这个概念最慢的理解。

相反,您需要 read(byte[]) 变体或 read(byte[], int offset, int length) 变体(一个非常简单,performance-wise 基本上是免费的,围绕 3 参数方法的包装器)。

使用 read() 的 'overhead' 范围从 'slight'(如果涉及缓冲区)到 'a factor 1000x'(如果不涉及)。如果是第二个,您可以通过将输入流包装在 BufferedInputStream 中并从中读取来回到 'slight' 开销。

但无论发生什么,这:

int toRead = 1000;
byte[] data = new byte[toRead];
int readSoFar = 0;
while (readSoFar < toRead) {
  int read = in.read(data, readSoFar, toRead - readSoFar);
  if (read == -1) throw new IOException("Expected more data");
  toRead += read;
}

int toRead = 1000;
byte[] data = new byte[toRead];
while (toRead > 0) {
  data[toRead--] = in.read();
}

使用 scala 对这些示例的性能没有影响。