Skip to content

Commit 229c958

Browse files
mhansencopybara-github
authored andcommitted
Hoist SmallSortedMap.getNumArrayEntries() outside loops over array entries
This should slightly speed things up. Should be safe: these operations don't change the number of entries inside the loop. PiperOrigin-RevId: 650087172
1 parent cbb3abf commit 229c958

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

java/core/src/main/java/com/google/protobuf/FieldSet.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ public void makeImmutable() {
9999
if (isImmutable) {
100100
return;
101101
}
102-
for (int i = 0; i < fields.getNumArrayEntries(); ++i) {
102+
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
103+
for (int i = 0; i < n; ++i) {
103104
Entry<T, Object> entry = fields.getArrayEntryAt(i);
104105
if (entry.getValue() instanceof GeneratedMessageLite) {
105106
((GeneratedMessageLite<?, ?>) entry.getValue()).makeImmutable();
@@ -149,7 +150,8 @@ public FieldSet<T> clone() {
149150
// We can't just call fields.clone because List objects in the map
150151
// should not be shared.
151152
FieldSet<T> clone = FieldSet.newFieldSet();
152-
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
153+
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
154+
for (int i = 0; i < n; i++) {
153155
Map.Entry<T, Object> entry = fields.getArrayEntryAt(i);
154156
clone.setField(entry.getKey(), entry.getValue());
155157
}
@@ -184,7 +186,8 @@ public Map<T, Object> getAllFields() {
184186
private static <T extends FieldDescriptorLite<T>> SmallSortedMap<T, Object> cloneAllFieldsMap(
185187
SmallSortedMap<T, Object> fields, boolean copyList, boolean resolveLazyFields) {
186188
SmallSortedMap<T, Object> result = SmallSortedMap.newFieldMap();
187-
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
189+
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
190+
for (int i = 0; i < n; i++) {
188191
cloneFieldEntry(result, fields.getArrayEntryAt(i), copyList, resolveLazyFields);
189192
}
190193
for (Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
@@ -426,7 +429,8 @@ private static boolean isValidType(final WireFormat.FieldType type, final Object
426429
* caller to check that all required fields are present.
427430
*/
428431
public boolean isInitialized() {
429-
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
432+
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
433+
for (int i = 0; i < n; i++) {
430434
if (!isInitialized(fields.getArrayEntryAt(i))) {
431435
return false;
432436
}
@@ -484,7 +488,8 @@ static int getWireFormatForFieldType(final WireFormat.FieldType type, boolean is
484488

485489
/** Like {@link Message.Builder#mergeFrom(Message)}, but merges from another {@link FieldSet}. */
486490
public void mergeFrom(final FieldSet<T> other) {
487-
for (int i = 0; i < other.fields.getNumArrayEntries(); i++) {
491+
int n = other.fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
492+
for (int i = 0; i < n; i++) {
488493
mergeFromField(other.fields.getArrayEntryAt(i));
489494
}
490495
for (final Map.Entry<T, Object> entry : other.fields.getOverflowEntries()) {
@@ -571,7 +576,8 @@ public static Object readPrimitiveField(
571576

572577
/** See {@link Message#writeTo(CodedOutputStream)}. */
573578
public void writeTo(final CodedOutputStream output) throws IOException {
574-
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
579+
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
580+
for (int i = 0; i < n; i++) {
575581
final Map.Entry<T, Object> entry = fields.getArrayEntryAt(i);
576582
writeField(entry.getKey(), entry.getValue(), output);
577583
}
@@ -582,7 +588,8 @@ public void writeTo(final CodedOutputStream output) throws IOException {
582588

583589
/** Like {@link #writeTo} but uses MessageSet wire format. */
584590
public void writeMessageSetTo(final CodedOutputStream output) throws IOException {
585-
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
591+
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
592+
for (int i = 0; i < n; i++) {
586593
writeMessageSetTo(fields.getArrayEntryAt(i), output);
587594
}
588595
for (final Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
@@ -759,7 +766,8 @@ public static void writeField(
759766
*/
760767
public int getSerializedSize() {
761768
int size = 0;
762-
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
769+
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
770+
for (int i = 0; i < n; i++) {
763771
final Map.Entry<T, Object> entry = fields.getArrayEntryAt(i);
764772
size += computeFieldSize(entry.getKey(), entry.getValue());
765773
}
@@ -772,7 +780,8 @@ public int getSerializedSize() {
772780
/** Like {@link #getSerializedSize} but uses MessageSet wire format. */
773781
public int getMessageSetSerializedSize() {
774782
int size = 0;
775-
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
783+
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
784+
for (int i = 0; i < n; i++) {
776785
size += getMessageSetSerializedSize(fields.getArrayEntryAt(i));
777786
}
778787
for (final Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
@@ -976,7 +985,8 @@ private FieldSet<T> buildImpl(boolean partial) {
976985

977986
private static <T extends FieldDescriptorLite<T>> void replaceBuilders(
978987
SmallSortedMap<T, Object> fieldMap, boolean partial) {
979-
for (int i = 0; i < fieldMap.getNumArrayEntries(); i++) {
988+
int n = fieldMap.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
989+
for (int i = 0; i < n; i++) {
980990
replaceBuilders(fieldMap.getArrayEntryAt(i), partial);
981991
}
982992
for (Map.Entry<T, Object> entry : fieldMap.getOverflowEntries()) {
@@ -1268,7 +1278,8 @@ private void verifyType(final T descriptor, final Object value) {
12681278
* caller to check that all required fields are present.
12691279
*/
12701280
public boolean isInitialized() {
1271-
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
1281+
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
1282+
for (int i = 0; i < n; i++) {
12721283
if (!FieldSet.isInitialized(fields.getArrayEntryAt(i))) {
12731284
return false;
12741285
}
@@ -1286,7 +1297,8 @@ public boolean isInitialized() {
12861297
*/
12871298
public void mergeFrom(final FieldSet<T> other) {
12881299
ensureIsMutable();
1289-
for (int i = 0; i < other.fields.getNumArrayEntries(); i++) {
1300+
int n = other.fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
1301+
for (int i = 0; i < n; i++) {
12901302
mergeFromField(other.fields.getArrayEntryAt(i));
12911303
}
12921304
for (final Map.Entry<T, Object> entry : other.fields.getOverflowEntries()) {

0 commit comments

Comments
 (0)