Wrap StreamEncoder in a BufferedWriter to avoid allocations

Change-Id: I24c9fada2735a912fb38c11090e7995cb826cf5d
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
index e2751e8..3985b92 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
@@ -32,6 +32,7 @@
 import com.google.common.net.HttpHeaders;
 import com.google.gson.FieldNamingPolicy;
 import com.google.gson.GsonBuilder;
+import java.io.BufferedWriter;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -397,7 +398,10 @@
   }
 
   protected static Writer newWriter(OutputStream os, HttpServletResponse res) throws IOException {
-    return new OutputStreamWriter(os, res.getCharacterEncoding());
+    // StreamEncoder#write(int) is wasteful with its allocations, and we don't have much control
+    // over whether library code calls that variant as opposed to the saner write(char[], int, int).
+    // Protect against this by buffering.
+    return new BufferedWriter(new OutputStreamWriter(os, res.getCharacterEncoding()));
   }
 
   private Writer newWriter(HttpServletRequest req, HttpServletResponse res) throws IOException {