Я просто нахожу в презентации по обмену опытом от 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;
}
}