I would like to obtain a few comments in regards to optimising my method created for writing of the whole content’s of StringBuilder to a ServletResponse.
I did it to avoid creation of gigantic Strings at a single go before passing it to the out.write() method. In my situation a StringBuilder’s content length, in some occasions, arrives at few million characters.
public static void writeResponse(ServletResponse response, StringBuilder sb) throws IOException {
try (PrintWriter out = response.getWriter()) {
int length = sb.length();
//to avoid creation of gigantic strings we are writing substrings from the sb
int bufferSize = (response.getBufferSize() != 0? response.getBufferSize():10000);
log.log(Level.INFO, "READY TO SEND To CLIENT, length of responseSB={0}", length);
if (length <= bufferSize) {
out.write(sb.toString());
} else {
int noWrites = length / bufferSize;
for (int i = 0; i < noWrites; i++) {
out.write(sb.substring(i * bufferSize, (i + 1) * bufferSize));
log.log(Level.INFO, "SENDING To CLIENT, write no={0} of {1}", new Object[]{(i + 1), noWrites});
}
int rest = length % bufferSize;
if (rest != 0) {
out.write(sb.substring(length - rest, length));
}
}
}
}
I want it to write a single (not chunked) message. Thus, I would like to know how accurately establish a response’s buffer size in relation to a number of characters (or a String’s length) it can fit?
At the moment, I am taking the current buffer size and using it as if it was expressing a number of characters it can fit, how to correctly evaluate the buffer size? Also I am not including the header size, how could I achieve it?
I would like to optimise its performance to maximum (so it works the fastest), any suggestion is much appreciated. Or maybe there is all together a better way of writing a gigantic StringBuilder content to ServletResponse?
The fastest way is:
If you want to save on memory, replace
StringBuilderwithPrintWriterand passresponse.getWriter()around.Any optimization regarding buffer sizes will only make things slower. Without optimization, the cost is roughly:
StringBuilder.toString()+out.write()which passed the long string to the container for chunking/sending.With your optimization, it looks like this:
StringBuilder.toString()+substring()+out.write()+ copying substring into send buffer + many calls to container to send the pieces.If you get rid of the builder, the number of calls to the container will stay the same (
out.write()uses an internal buffer) but you won’t waste memory to keep data around.If you want to keep the
StringBuilder, then find out how big the pages are and create aStringBuilderwith a non-default size so it doesn’t have to extend it’s internal buffer all the time.