@Test
  public void testOptimizedSerializationDefaultDeserialization() throws Exception {

    TestAllTypes message = createSampleMessage();

    byte[] data = TestAllTypesSerializer.serialize(message);

    protobuf_unittest.UnittestProto.TestAllTypes result =
        protobuf_unittest.UnittestProto.TestAllTypes.parseFrom(data);
    assertNotNull(result);
    assertDeepEquals(result, message);
    assertTrue(result.getUnknownFields().asMap().isEmpty());
  }
  @Test
  public void testOptimizedSerializeToStreamDefaultDeserialization() throws Exception {

    TestAllTypes message = createSampleMessage();

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    TestAllTypesSerializer.serialize(message, baos);

    protobuf_unittest.UnittestProto.TestAllTypes result =
        protobuf_unittest.UnittestProto.TestAllTypes.parseFrom(baos.toByteArray());
    assertNotNull(result);
    assertDeepEquals(result, message);
    assertTrue(result.getUnknownFields().asMap().isEmpty());
  }
  @Test
  public void testDefaultSerializationOptimizedDeserialization() throws Exception {
    TestAllTypes message = createSampleMessage();
    byte[] data = TestAllTypesSerializer.serialize(message);

    protobuf_unittest.UnittestProto.TestAllTypes result =
        protobuf_unittest.UnittestProto.TestAllTypes.parseFrom(data);

    byte[] defaultSerializationData = result.toByteArray();

    TestAllTypes optimizedResult = TestAllTypesSerializer.parseFrom(defaultSerializationData);
    assertDeepEquals(result, optimizedResult);
    assertEquals(2, optimizedResult.getRepeatedForeignMessage().size());
    assertEquals(1, optimizedResult.getRepeatedForeignMessage().get(0).getC());
    assertEquals(2, optimizedResult.getRepeatedForeignMessage().get(1).getC());
  }
 private static void assertDeepEquals(
     protobuf_unittest.UnittestProto.TestAllTypes defaultImpl, TestAllTypes optimized) {
   assertEquals(defaultImpl.getOptionalInt32(), optimized.getOptionalInt32());
   assertEquals(defaultImpl.getOptionalInt64(), optimized.getOptionalInt64());
   assertEquals(defaultImpl.getOptionalUint32(), optimized.getOptionalUint32());
   assertEquals(defaultImpl.getOptionalUint64(), optimized.getOptionalUint64());
   assertEquals(defaultImpl.getOptionalSint32(), optimized.getOptionalSint32());
   assertEquals(defaultImpl.getOptionalSint64(), optimized.getOptionalSint64());
   assertEquals(defaultImpl.getOptionalFixed32(), optimized.getOptionalFixed32());
   assertEquals(defaultImpl.getOptionalFixed64(), optimized.getOptionalFixed64());
   assertEquals(defaultImpl.getOptionalSfixed32(), optimized.getOptionalSfixed32());
   assertEquals(defaultImpl.getOptionalSfixed64(), optimized.getOptionalSfixed64());
   assertEquals(defaultImpl.getOptionalFloat(), optimized.getOptionalFloat(), 0.0);
   assertEquals(defaultImpl.getOptionalDouble(), optimized.getOptionalDouble(), 0.0);
   assertEquals(defaultImpl.getOptionalBool(), optimized.getOptionalBool());
   assertEquals(defaultImpl.getOptionalString(), optimized.getOptionalString());
   assertTrue(
       Arrays.equals(defaultImpl.getOptionalBytes().toByteArray(), optimized.getOptionalBytes()));
   assertEquals(defaultImpl.getOptionalStringPiece(), optimized.getOptionalStringPiece());
   assertEquals(defaultImpl.getOptionalCord(), optimized.getOptionalCord());
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedInt32List().toArray(), optimized.getRepeatedInt32().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedInt64List().toArray(), optimized.getRepeatedInt64().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedUint32List().toArray(),
           optimized.getRepeatedUint32().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedUint64List().toArray(),
           optimized.getRepeatedUint64().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedSint32List().toArray(),
           optimized.getRepeatedSint32().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedSint64List().toArray(),
           optimized.getRepeatedSint64().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedFixed32List().toArray(),
           optimized.getRepeatedFixed32().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedFixed64List().toArray(),
           optimized.getRepeatedFixed64().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedSfixed32List().toArray(),
           optimized.getRepeatedSfixed32().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedSfixed64List().toArray(),
           optimized.getRepeatedSfixed64().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedFloatList().toArray(), optimized.getRepeatedFloat().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedDoubleList().toArray(),
           optimized.getRepeatedDouble().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedBoolList().toArray(), optimized.getRepeatedBool().toArray()));
   assertTrue(
       Arrays.equals(
           defaultImpl.getRepeatedStringList().toArray(),
           optimized.getRepeatedString().toArray()));
   assertEquals(
       defaultImpl.getRepeatedForeignMessageCount(), optimized.getRepeatedForeignMessage().size());
   assertEquals(
       defaultImpl.getRepeatedForeignMessage(0).getC(),
       optimized.getRepeatedForeignMessage().get(0).getC());
   assertEquals(
       defaultImpl.getRepeatedForeignMessage(1).getC(),
       optimized.getRepeatedForeignMessage().get(1).getC());
 }
  public static void main(String[] args) throws Exception {

    long times = 1000000;

    long start;

    TestAllTypes message = createSampleMessage();
    byte[] data = TestAllTypesSerializer.serialize(message);

    start = System.currentTimeMillis();
    for (int i = 0; i < times; i++) {
      TestAllTypesSerializer.serialize(message);
    }
    System.out.println(" * Optimized version(serialize): " + (System.currentTimeMillis() - start));
    protobuf_unittest.UnittestProto.TestAllTypes result =
        protobuf_unittest.UnittestProto.TestAllTypes.parseFrom(data);

    start = System.currentTimeMillis();
    for (int i = 0; i < times; i++) {
      result.toByteArray();
    }
    System.out.println(" * Default version(serialize): " + (System.currentTimeMillis() - start));

    ByteArrayOutputStream baos =
        new ByteArrayOutputStream(
            data.length
                + 10); // little trick to remove stream io issues and measure pure serialization
    // power.

    start = System.currentTimeMillis();
    for (int i = 0; i < times; i++) {
      TestAllTypesSerializer.serialize(message, baos);
      baos.reset();
    }
    System.out.println(
        " * Optimized streamed version(serialize): " + (System.currentTimeMillis() - start));

    start = System.currentTimeMillis();
    for (int i = 0; i < times; i++) {
      result.writeTo(baos);
      baos.reset();
    }
    System.out.println(
        " * Default streamed version(serialize): " + (System.currentTimeMillis() - start));

    start = System.currentTimeMillis();
    for (int i = 0; i < times; i++) {
      TestAllTypesSerializer.parseFrom(data);
    }
    System.out.println(
        " * Optimized version(de-serialize): " + (System.currentTimeMillis() - start));

    start = System.currentTimeMillis();
    for (int i = 0; i < times; i++) {
      protobuf_unittest.UnittestProto.TestAllTypes.parseFrom(data);
    }
    System.out.println(" * Default version(de-serialize): " + (System.currentTimeMillis() - start));

    ByteArrayInputStream bais = new ByteArrayInputStream(data);

    start = System.currentTimeMillis();
    for (int i = 0; i < times; i++) {
      TestAllTypesSerializer.parseFrom(bais);
      bais.reset();
    }
    System.out.println(
        " * Optimized streamed version(de-serialize): " + (System.currentTimeMillis() - start));

    start = System.currentTimeMillis();
    for (int i = 0; i < times; i++) {
      protobuf_unittest.UnittestProto.TestAllTypes.parseFrom(bais);
      bais.reset();
    }
    System.out.println(
        " * Default streamed version(de-serialize): " + (System.currentTimeMillis() - start));
  }