Эх сурвалжийг харах

Use cached value for type safety check during unpacking of Any message (#5698)

This performance optimization allows to skip reflection (in the is() method) when the message has been already unpacked once
Yuri Vanin 6 жил өмнө
parent
commit
7fdc45a854

+ 8 - 4
src/google/protobuf/compiler/java/java_message.cc

@@ -1446,13 +1446,17 @@ void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
     "public <T extends com.google.protobuf.Message> T unpack(\n"
     "public <T extends com.google.protobuf.Message> T unpack(\n"
     "    java.lang.Class<T> clazz)\n"
     "    java.lang.Class<T> clazz)\n"
     "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
     "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
-    "  if (!is(clazz)) {\n"
+    "  boolean invalidClazz = false;\n"
+    "  if (cachedUnpackValue != null) {\n"
+    "    if (cachedUnpackValue.getClass() == clazz) {\n"
+    "      return (T) cachedUnpackValue;\n"
+    "    }\n"
+    "    invalidClazz = true;\n"
+    "  }\n"
+    "  if (invalidClazz || !is(clazz)) {\n"
     "    throw new com.google.protobuf.InvalidProtocolBufferException(\n"
     "    throw new com.google.protobuf.InvalidProtocolBufferException(\n"
     "        \"Type of the Any message does not match the given class.\");\n"
     "        \"Type of the Any message does not match the given class.\");\n"
     "  }\n"
     "  }\n"
-    "  if (cachedUnpackValue != null) {\n"
-    "    return (T) cachedUnpackValue;\n"
-    "  }\n"
     "  T defaultInstance =\n"
     "  T defaultInstance =\n"
     "      com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
     "      com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
     "  T result = (T) defaultInstance.getParserForType()\n"
     "  T result = (T) defaultInstance.getParserForType()\n"