Оптимизация записи содержимого StringBuilder в ServletResponse - PullRequest
2 голосов
/ 08 марта 2012

Я хотел бы получить несколько комментариев относительно оптимизации моего метода, созданного для записи всего содержимого StringBuilder в ServletResponse.

Я сделал это, чтобы избежать создания гигантских строк за один раз, прежде чем передавать его в метод out.write ().В моей ситуации длина содержимого StringBuilder в некоторых случаях достигает нескольких миллионов символов.

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));
            }
        }
    }
}

Я хочу написать одно (не разделенное на части) сообщение.Таким образом, Я хотел бы знать, как точно установить размер буфера ответа по отношению к числу символов (или длине строки), которое он может уместить?

В данный момент я беру текущий размер буфера и использую его, как если бы он выражал количество символов, которые он может уместить, как правильно оценить размер буфера?Кроме того, я не , включая размер заголовка, как я могу его достичь ?

Я хотел бы оптимизировать его производительность до максимума (чтобы он работал быстрее) ,Любое предложение высоко ценится.Или, может быть, есть все вместе лучший способ записи гигантского контента StringBuilder в ServletResponse?

1 Ответ

4 голосов
/ 08 марта 2012

Самый быстрый способ:

out.write(sb.toString());

Если вы хотите сэкономить на памяти, замените StringBuilder на PrintWriter и передайте response.getWriter() вокруг.

Любая оптимизация в отношении размеров буфера будет только замедлять работу. Без оптимизации стоимость примерно равна: StringBuilder.toString() + out.write(), которая передала длинную строку в контейнер для разбиения на фрагменты / отправки.

С вашей оптимизацией это выглядит так: StringBuilder.toString() + substring() + out.write() + копирование подстроки в буфер отправки + много вызовов в контейнер для отправки кусков.

Если вы избавитесь от компоновщика, количество обращений к контейнеру останется прежним (out.write() использует внутренний буфер), но вы не будете тратить память на хранение данных.

Если вы хотите сохранить StringBuilder, выясните, насколько велики страницы, и создайте StringBuilder с размером не по умолчанию, чтобы ему не приходилось постоянно расширять свой внутренний буфер.

...