Optimize `proto2::util::MessageDifferencer::RetrieveFields`.
`tmp_message_fields_` was added to reduce repeated allocations of vectors. However, we are copying from `tmp_message_fields_` to another local vector `message_fields` and then returning this local vector. So, might as well just use `message_fields` directly.
PiperOrigin-RevId: 812231145
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index 79c268e..4e2f73a 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -18,6 +18,7 @@
#include <limits>
#include <memory>
#include <utility>
+#include <vector>
#include "google/protobuf/descriptor.pb.h"
#include "absl/container/flat_hash_map.h"
@@ -653,29 +654,26 @@
const Message& message, bool base_message) {
const Descriptor* descriptor = message.GetDescriptor();
- tmp_message_fields_.clear();
- tmp_message_fields_.reserve(descriptor->field_count() + 1);
+ std::vector<const FieldDescriptor*> message_fields;
+ message_fields.reserve(descriptor->field_count() + 1);
const Reflection* reflection = message.GetReflection();
if (descriptor->options().map_entry()) {
if (this->scope_ == PARTIAL && base_message) {
- reflection->ListFields(message, &tmp_message_fields_);
+ reflection->ListFields(message, &message_fields);
} else {
// Map entry fields are always considered present.
for (int i = 0; i < descriptor->field_count(); i++) {
- tmp_message_fields_.push_back(descriptor->field(i));
+ message_fields.push_back(descriptor->field(i));
}
}
} else {
- reflection->ListFields(message, &tmp_message_fields_);
+ reflection->ListFields(message, &message_fields);
}
// Add sentinel values to deal with the
// case where the number of the fields in
// each list are different.
- tmp_message_fields_.push_back(nullptr);
-
- std::vector<const FieldDescriptor*> message_fields(
- tmp_message_fields_.begin(), tmp_message_fields_.end());
+ message_fields.push_back(nullptr);
return message_fields;
}
@@ -768,7 +766,8 @@
size_t index1 = 0;
size_t index2 = 0;
- tmp_message_fields_.clear();
+ std::vector<const FieldDescriptor*> combined_fields;
+ combined_fields.reserve(1 + std::max(fields1.size(), fields2.size()));
while (index1 < fields1.size() && index2 < fields2.size()) {
const FieldDescriptor* field1 = fields1[index1];
@@ -776,12 +775,12 @@
if (FieldBefore(field1, field2)) {
if (fields1_scope == FULL) {
- tmp_message_fields_.push_back(field1);
+ combined_fields.push_back(field1);
}
++index1;
} else if (FieldBefore(field2, field1)) {
if (fields2_scope == FULL) {
- tmp_message_fields_.push_back(field2);
+ combined_fields.push_back(field2);
} else if (fields2_scope == PARTIAL &&
ShouldCompareNoPresence(message1, *reflection1, field2)) {
// In order to make MessageDifferencer play nicely with no-presence
@@ -792,20 +791,17 @@
// value) but will not appear in fields1 (since they have the default
// value or were never set).
force_compare_no_presence_fields_.insert(field2);
- tmp_message_fields_.push_back(field2);
+ combined_fields.push_back(field2);
}
++index2;
} else {
- tmp_message_fields_.push_back(field1);
+ combined_fields.push_back(field1);
++index1;
++index2;
}
}
- tmp_message_fields_.push_back(nullptr);
-
- std::vector<const FieldDescriptor*> combined_fields(
- tmp_message_fields_.begin(), tmp_message_fields_.end());
+ combined_fields.push_back(nullptr);
return combined_fields;
}
diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h
index 04188e8..5f97878 100644
--- a/src/google/protobuf/util/message_differencer.h
+++ b/src/google/protobuf/util/message_differencer.h
@@ -961,8 +961,6 @@
map_field_key_comparator_;
MapEntryKeyComparator map_entry_key_comparator_;
std::vector<std::unique_ptr<IgnoreCriteria>> ignore_criteria_;
- // Reused multiple times in RetrieveFields to avoid extra allocations
- std::vector<const FieldDescriptor*> tmp_message_fields_;
absl::flat_hash_set<const FieldDescriptor*> ignored_fields_;