Browse Source

ObjC: small improvement to extension serialization.

For messages that have multiple extension ranges, this will improve things
by avoiding repeated work.  For messages with a single range, it should
be a wash.

- Sort the list of set extensions once during serialization and reuse the list.
- Break out of the serialization loop as soon as the loop has moved pasted at
  accepted range for field ids.
Thomas Van Lenten 6 years ago
parent
commit
ffa6bfc01a
1 changed files with 15 additions and 8 deletions
  1. 15 8
      objectivec/GPBMessage.m

+ 15 - 8
objectivec/GPBMessage.m

@@ -1283,16 +1283,20 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
   NSUInteger fieldCount = fieldsArray.count;
   const GPBExtensionRange *extensionRanges = descriptor.extensionRanges;
   NSUInteger extensionRangesCount = descriptor.extensionRangesCount;
+  NSArray *sortedExtensions =
+      [[extensionMap_ allKeys] sortedArrayUsingSelector:@selector(compareByFieldNumber:)];
   for (NSUInteger i = 0, j = 0; i < fieldCount || j < extensionRangesCount;) {
     if (i == fieldCount) {
       [self writeExtensionsToCodedOutputStream:output
-                                         range:extensionRanges[j++]];
+                                         range:extensionRanges[j++]
+                              sortedExtensions:sortedExtensions];
     } else if (j == extensionRangesCount ||
                GPBFieldNumber(fieldsArray[i]) < extensionRanges[j].start) {
       [self writeField:fieldsArray[i++] toCodedOutputStream:output];
     } else {
       [self writeExtensionsToCodedOutputStream:output
-                                         range:extensionRanges[j++]];
+                                         range:extensionRanges[j++]
+                              sortedExtensions:sortedExtensions];
     }
   }
   if (descriptor.isWireFormat) {
@@ -1808,17 +1812,20 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
 }
 
 - (void)writeExtensionsToCodedOutputStream:(GPBCodedOutputStream *)output
-                                     range:(GPBExtensionRange)range {
-  NSArray *sortedExtensions = [[extensionMap_ allKeys]
-      sortedArrayUsingSelector:@selector(compareByFieldNumber:)];
+                                     range:(GPBExtensionRange)range
+                          sortedExtensions:(NSArray *)sortedExtensions {
   uint32_t start = range.start;
   uint32_t end = range.end;
   for (GPBExtensionDescriptor *extension in sortedExtensions) {
     uint32_t fieldNumber = extension.fieldNumber;
-    if (fieldNumber >= start && fieldNumber < end) {
-      id value = [extensionMap_ objectForKey:extension];
-      GPBWriteExtensionValueToOutputStream(extension, value, output);
+    if (fieldNumber < start) {
+      continue;
+    }
+    if (fieldNumber >= end) {
+      break;
     }
+    id value = [extensionMap_ objectForKey:extension];
+    GPBWriteExtensionValueToOutputStream(extension, value, output);
   }
 }