[英]How can I increase performance on reading the InputStream?
This very well may just be a KISS moment, but I feel like I should ask anyway.这很可能只是一个 KISS 时刻,但我觉得无论如何我都应该问。
I have a thread and it's reading from a sockets InputStream.我有一个线程,它正在从 sockets InputStream 读取。 Since I am dealing in particularly small data sizes (as in the data that I can expect to recieve from is in the order of 100 - 200 bytes), I set the buffer array size to 256. As part of my read function I have a check that will ensure that when I read from the InputStream that I got all of the data.
由于我正在处理特别小的数据大小(因为我可以期望接收的数据大约为 100 - 200 字节),我将缓冲区数组大小设置为 256。作为我读取 function 的一部分,我有一个检查这将确保当我从 InputStream 中读取所有数据时。 If I didn't then I will recursively call the read function again.
如果我没有,那么我将再次递归调用读取 function。 For each recursive call I merge the two buffer arrays back together.
对于每个递归调用,我将两个缓冲区 arrays 重新合并在一起。
My problem is, while I never anticipate using more than the buffer of 256, I want to be safe.我的问题是,虽然我从没想过会使用超过 256 的缓冲区,但我想保证安全。 But if sheep begin to fly and the buffer is significantly more the read the function (by estimation) will begin to take an exponential curve more time to complete.
但是,如果羊开始飞行并且缓冲区明显更多,则读取 function(据估计)将开始需要更多时间才能完成指数曲线。
How can I increase the effiency of the read function and/or the buffer merging?如何提高读取 function 和/或缓冲区合并的效率?
Here is the read function as it stands.这是 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;
}
EDIT: Am I being paranoid (unjustifiedly) and should just set the buffer to 2048 and call it done?编辑:我是偏执狂(不合理),应该将缓冲区设置为 2048 并称之为完成吗?
BufferedInputStream
, as noted by Roland, and DataInputStream.readFully()
, which replaces all the looping code. Roland 指出的
BufferedInputStream
和DataInputStream.readFully()
,它替换了所有循环代码。
int BUFFER_AMOUNT = 256;
Should be final if you don't want it changing at runtime.如果您不希望它在运行时更改,则应该是最终的。
if (bytes == -1) {
Should be !=应该是!=
Also, I'm not entirely clear on what you're trying to accomplish with this code.此外,我并不完全清楚您要使用此代码完成什么。 Do you mind shedding some light on that?
你介意对此有所了解吗?
I have no idea what you mean by "small data sizes".我不知道您所说的“小数据量”是什么意思。 You should measure whether the time is spent in kernel mode (then you are issuing too many
read
s directly on the socket) or in user mode (then your algorithm is too complicated).您应该衡量时间是在 kernel 模式(那么您直接在套接字上发出太多
read
)还是在用户模式(那么您的算法太复杂)。
In the former case, just wrap the input with a BufferedInputStream
with 4096 bytes of buffer and read from it.在前一种情况下,只需使用
BufferedInputStream
包装输入,其中包含 4096 字节的缓冲区并从中读取。
In the latter case, just use this code:在后一种情况下,只需使用以下代码:
/**
* 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;
}
This code completely avoids creating new objects, calling unnecessary methods and furthermore --- it is straightforward.这段代码完全避免了创建新对象、调用不必要的方法等等——它很简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.