Reputation: 2343
I was wondering if there is any performance issue related to read just one byte from AsynchronousSocketChannel. I am implementing a simple HTTP server and parsing a request where I need read byte per byte:
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);
}
Can a Java expert explain me if that practice is bad or not in terms of performance?
Upvotes: 0
Views: 696
Reputation: 2343
Well! I found a more efficient way to deal with this! I allocated ByteBuffer with a min size! The bad thing is that I introduced some complexity in the parser. But anyway...
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();
}
Upvotes: 0
Reputation: 106361
Normally you would try to read in as many bytes as possible into the buffer, all at once. This is significantly more efficient: ByteBuffers are highly optimised for reads and writes of big sequential chunks of bytes.
However, you can still make ByteBuffers work with a buffer size of one. If the volume of byte reads is smallish (say, 100,000 bytes per second or less) then I doubt it will make any noticeable difference. Your code looks fine for handling that sort of volume. As always, you should benchmark if you think it is a real concern, but there's little point optimising code if it is already fast enough for your needs.
But more seriously, I would question why you are writing this kind of code at all? Why not use a well tested library like (e.g. Netty) which should do all of this sort of stuff for you?
Upvotes: 2