Performance tuning: Reading servlet request body
We are having a performance problem in our application - particularly when the browser client submits large volume of POST data to the server.
The bottleneck is in reading the servlet request body into a Stringbuffer - which we have observed timings above 10 seconds for large requests: (800 - 1400 KB - which, from the browsers perspective translates to anything between 800,000 - 1,500,000 characters)
StringBuilder strBuilder = new StringBuilder(2 ^ 19);
InputStreamReader isr = new InputStreamReader(request.getInputStream());
BufferedReader bufReader = new BufferedReader(isr);
char[] charBuffer = new char[2 ^ 19];
for (int readCount = bufReader.read(charBuffer); readCount > -1; readCount = bufReader.read(charBuffer))
{
strBuilder.append(charBuffer, 0, readCount);
}
Some points to note:
- The 'reader' variable in the code sample above corresponds to javax.servlet.ServletRequest class
- Initially, the char buffer size was at 128, and no-arg StringBuilder.
- I subsequently increased this to 2^19 to minimise the number of iterations, and resizing of the internal char buffer used by the StringBuilder for large input requests (for the examples detailed above)
Yes, I have a nagging feeling there may be greater scalability issues lurking behind this problem :-).
However, before re-evaluating the design of the application, I would like to know whether there are any optimisations around this code block which I could try.Any suggestions would be much appreciated.开发者_如何学Python
You already have an implicit buffer thanks to BufferedReader
, yet you're reading from that into another buffer (char[]
) before appending to the StringBuilder
. Just read one char
at a time from the BufferedReader
and append it. I believe the default buffer size for BufferedReader
is 8K, so you can always try a different size to see if that helps. Have you inspected the amount of time being spent in GC?
The answer was glaring at me all the time...
2 ^ 19 gets compiled into 17 - as it is the bitwise exclusive OR operator, and not signed left shift :-)
There is probably a lesson to be learned here, not sure which - empirical analysis of the efficacy of peer review, or admonitions against late-night coding - I'm yet to make up my mind.
Might serve as a useful Java Puzzler though, Neal Gafter if you are reading this!
精彩评论