簡體   English   中英

如何提高讀取 InputStream 的性能?

[英]How can I increase performance on reading the InputStream?

這很可能只是一個 KISS 時刻,但我覺得無論如何我都應該問。

我有一個線程,它正在從 sockets InputStream 讀取。 由於我正在處理特別小的數據大小(因為我可以期望接收的數據大約為 100 - 200 字節),我將緩沖區數組大小設置為 256。作為我讀取 function 的一部分,我有一個檢查這將確保當我從 InputStream 中讀取所有數據時。 如果我沒有,那么我將再次遞歸調用讀取 function。 對於每個遞歸調用,我將兩個緩沖區 arrays 重新合並在一起。

我的問題是,雖然我從沒想過會使用超過 256 的緩沖區,但我想保證安全。 但是,如果羊開始飛行並且緩沖區明顯更多,則讀取 function(據估計)將開始需要更多時間才能完成指數曲線。

如何提高讀取 function 和/或緩沖區合並的效率?

這是 function 的原樣。

int BUFFER_AMOUNT = 256;

private int read(byte[] buffer) throws IOException {
   int bytes = mInStream.read(buffer); // Read the input stream

   if (bytes == -1) { // If bytes == -1 then we didn't get all of the data

        byte[] newBuffer = new byte[BUFFER_AMOUNT]; // Try to get the rest
        int newBytes;
        newBytes = read(newBuffer); // Recurse until we have all the data

        byte[] oldBuffer = new byte[bytes + newBytes]; // make the final array size

        // Merge buffer into the begining of old buffer.
        // We do this so that once the method finishes, we can just add the 
        // modified buffer to a queue later in the class for processing.
        for (int i = 0; i < bytes; i++) 
            oldBuffer[i] = buffer[i];

        for (int i = bytes; i < bytes + newBytes; i++) // Merge newBuffer into the latter half of old Buffer
            oldBuffer[i] = newBuffer[i];
        // Used for the recursion

        buffer = oldBuffer; // And now we set buffer to the new buffer full of all the data.
        return bytes + newBytes;
    }
    return bytes;
}

編輯:我是偏執狂(不合理),應該將緩沖區設置為 2048 並稱之為完成嗎?

Roland 指出的BufferedInputStreamDataInputStream.readFully() ,它替換了所有循環代碼。

int BUFFER_AMOUNT = 256;

如果您不希望它在運行時更改,則應該是最終的。

if (bytes == -1) {

應該是!=

此外,我並不完全清楚您要使用此代碼完成什么。 你介意對此有所了解嗎?

我不知道您所說的“小數據量”是什么意思。 您應該衡量時間是在 kernel 模式(那么您直接在套接字上發出太多read )還是在用戶模式(那么您的算法太復雜)。

在前一種情況下,只需使用BufferedInputStream包裝輸入,其中包含 4096 字節的緩沖區並從中讀取。

在后一種情況下,只需使用以下代碼:

/**
  * Reads as much as possible from the stream.
  * @return The number of bytes read into the buffer, or -1
  *         if nothing has been read because the end of file has been reached.
  */
static int readGreedily(InputStream is, byte[] buf, int start, int len) {
  int nread;
  int ptr = start; // index at which the data is put into the buffer
  int rest = len; // number of bytes that we still want to read

  while ((nread = is.read(buf, ptr, rest)) > 0) {
    ptr += nread;
    rest -= nread;
  }

  int totalRead = len - rest;
  return (nread == -1 && totalRead == 0) ? -1 : totalRead;
}

這段代碼完全避免了創建新對象、調用不必要的方法等等——它很簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM