我想知道是否存在与从AsynchronousSocketChannel读取一个字节有关的任何性能问题。我正在实现一个简单的HTTP服务器并解析我需要每字节读取字节的请求:
ByteBuffer dst = ByteBuffer.allocate(1);
int end = 0;
int br = 0;
int bread = 0;
StringBuilder sb = new StringBuilder();
while(bread < RCV_BUF){
br = client.read(dst).get();
//End of stream and nothing :(
if(br == 0){
return null;
}
dst.flip();
bread += br;
byte b = dst.get();
dst.clear();
if((end == 0 && b == '\r') || (end == 1 && b == '\n') || (end == 2 && b == '\r')){
end++;
}
else
if(end == 3 && b == '\n'){
break;
}
else
{
end = 0;
}
sb.append((char)b);
}
Java专家可以解释一下,如果这种做法在性能方面有差异吗?
答案 0 :(得分:2)
通常,您会尝试尽可能多地将字节读入缓冲区。这显着提高了效率:ByteBuffers针对大顺序字节块的读写进行了高度优化。
但是,您仍然可以使ByteBuffers的缓冲区大小为1。如果字节读取的数量很小(比如每秒100,000字节或更少),那么我怀疑它会产生明显的差异。您的代码看起来很适合处理那种卷。与往常一样,如果您认为这是一个真正的问题,您应该进行基准测试,但如果代码已经足够快以满足您的需求,那么优化代码就没什么意义了。
但更严重的是,我会质疑为什么你要写这种代码?为什么不使用经过良好测试的库(例如Netty),它应该为你做所有这些事情?
答案 1 :(得分:0)
嘛!我找到了一种更有效的方法来解决这个问题!我分配了最小尺寸的ByteBuffer!糟糕的是我在解析器中引入了一些复杂性。但无论如何......
int RCV_BUF = client.getOption(StandardSocketOptions.SO_RCVBUF);
ByteBuffer dst = ByteBuffer.allocate(256);
int end = 0;
int br = 0;
int bread = 0;
StringBuilder sb = new StringBuilder();
boolean endr = false;
boolean cr = false;
//Try parse headers
while(!endr && bread < RCV_BUF){
br = client.read(dst).get();
//End of stream and nothing :(
if(br == 0){
return null;
}
dst.flip();
bread += br;
while(dst.hasRemaining()){
byte b = dst.get();
if(end == 0 && b == '\r'){
end++;
continue;
}
// Possible header...
if(end == 1){
// We got a header!
if(b == '\n'){
// Reached the end of headers!
if(cr){
endr = true;
break;
}
cr = true;
end = 0;
System.out.println(sb.toString());
sb = new StringBuilder();
continue;
}
//Bad request (send a 400 status code...)!
return null;
}
if(cr){
cr = false;
}
sb.append((char)b);
}
dst.clear();
}