瀏覽代碼

Optimize Java serialization of small messages to streams. Patch from Evan Jones.

kenton@google.com 16 年之前
父節點
當前提交
f85d70f9e4

+ 2 - 0
CONTRIBUTORS.txt

@@ -76,3 +76,5 @@ Patch contributors:
     * HPUX support.
   Oliver Jowett <oliver.jowett@gmail.com>
     * Detect whether zlib is new enough in configure script.
+  Evan Jones <evanj@mit.edu>
+    * Optimize Java serialization code when writing a small message to a stream.

+ 9 - 2
java/src/main/java/com/google/protobuf/AbstractMessageLite.java

@@ -72,13 +72,20 @@ public abstract class AbstractMessageLite implements MessageLite {
   }
 
   public void writeTo(final OutputStream output) throws IOException {
-    final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
+    final int bufferSize =
+        CodedOutputStream.computePreferredBufferSize(getSerializedSize());
+    final CodedOutputStream codedOutput =
+        CodedOutputStream.newInstance(output, bufferSize);
     writeTo(codedOutput);
     codedOutput.flush();
   }
 
   public void writeDelimitedTo(final OutputStream output) throws IOException {
-    final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
+    final int serialized = getSerializedSize();
+    final int bufferSize = CodedOutputStream.computePreferredBufferSize(
+        CodedOutputStream.computeRawVarint32Size(serialized) + serialized);
+    final CodedOutputStream codedOutput =
+        CodedOutputStream.newInstance(output, bufferSize);
     codedOutput.writeRawVarint32(getSerializedSize());
     writeTo(codedOutput);
     codedOutput.flush();

+ 12 - 0
java/src/main/java/com/google/protobuf/CodedOutputStream.java

@@ -60,6 +60,18 @@ public final class CodedOutputStream {
    */
   public static final int DEFAULT_BUFFER_SIZE = 4096;
 
+  /**
+   * Returns the buffer size to efficiently write dataLength bytes to this
+   * CodedOutputStream. Used by AbstractMessageLite.
+   *
+   * @return the buffer size to efficiently write dataLength bytes to this
+   *         CodedOutputStream.
+   */
+  static int computePreferredBufferSize(int dataLength) {
+    if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE;
+    return dataLength;
+  }
+
   private CodedOutputStream(final byte[] buffer, final int offset,
                             final int length) {
     output = null;