От Char [] до Byte [] для оптимизации вывода в сети (Java) - PullRequest
1 голос
/ 13 августа 2011

Я просто нахожу в презентации по обмену опытом от infoq. Он утверждает, что если вы преобразуете String в byte [] в сервлете, это увеличит QPS (количество запросов в секунду?). Пример кода показывает сравнение:

До

private static String content = “…94k…”;
protected doGet(…){
response.getWrite().print(content);
}

После

private static String content = “…94k…”;
Private static byte[] bytes = content.getBytes();
protected doGet(…){
response.getOutputStream().write(bytes);
}

Результат до

  • размер страницы (K) 94
  • Макс. QPS 1800

Результат после

  • размер страницы (K) 94
  • Макс. QPS 3500

Может кто-нибудь объяснить, почему он был оптимизирован? Я верю, что это правда.

UPDATE

На случай, если я вас введу в заблуждение. Мне нужно объяснить, что оригинальная презентация использует это только в качестве примера. Таким образом, они фактически изменяют скорость двигателя. Но этот исходный код немного длинный.

На самом деле в презентации не подразумевалось, как они это делают подробно. Но я нашел немного свинца.

В ASTText.java они кэшировали байт [] ctext вместо char [] ctext, что значительно повышает производительность ~!

Так же, как и выше. Это имеет большой смысл, верно?

(НО, определенно, они также должны рефакторировать интерфейс Node. Writer не может записать байт []. Это означает, что вместо этого следует использовать OutputStream!)

Как и рекомендовал Perception, делегат Write, наконец, передается StreamEncoder. И запись StreamEncoder сначала изменит char [] на byte []. А затем делегируйте его в OutputSteam для реальной записи. Вы можете легко обратиться к исходному коду и доказать это. Учитывая, что метод рендеринга будет вызываться каждый раз для отображения страницы, экономия будет значительной.

StreamEncoder.class

 public class ASTText extends SimpleNode {
            private char[] ctext;
        /**
         * @param id
         */
        public ASTText(int id) {
            super (id);
        }

        /**
         * @param p
         * @param id
         */
        public ASTText(Parser p, int id) {
            super (p, id);
        }

        /**
         * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object)
         */
        public Object jjtAccept(ParserVisitor visitor, Object data) {
            return visitor.visit(this , data);
        }

    /**
     * @see org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)
     */
    public Object init(InternalContextAdapter context, Object data)
            throws TemplateInitException {
        Token t = getFirstToken();

        String text = NodeUtils.tokenLiteral(t);

        ctext = text.toCharArray();

        return data;
    }

    /**
     * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer)
     */
    public boolean render(InternalContextAdapter context, Writer writer)
            throws IOException {
        if (context.getAllowRendering()) {
            writer.write(ctext);
        }
        return true;
    }
}

1 Ответ

5 голосов
/ 13 августа 2011

Кроме того, что во втором примере вы не вызываете одни и те же методы вывода, вы избегаете дополнительных затрат на преобразование строки в байты перед записью ее в поток вывода.Эти сценарии не очень реалистичны, хотя динамическая природа веб-приложений не позволяет предварительно преобразовать все ваши модели данных в потоки байтов. И , сейчас нет серьезных архитектур, где вы будете писать прямо в поток вывода HTTP, как этот.

...