Skip to content

Commit

Permalink
Hoist SmallSortedMap.getNumArrayEntries() outside loops over array en…
Browse files Browse the repository at this point in the history
…tries

This should slightly speed things up.

Should be safe: these operations don't change the number of entries inside the loop.

PiperOrigin-RevId: 650087172
  • Loading branch information
mhansen authored and copybara-github committed Jul 8, 2024
1 parent cbb3abf commit 229c958
Showing 1 changed file with 24 additions and 12 deletions.
36 changes: 24 additions & 12 deletions java/core/src/main/java/com/google/protobuf/FieldSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ public void makeImmutable() {
if (isImmutable) {
return;
}
for (int i = 0; i < fields.getNumArrayEntries(); ++i) {
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
for (int i = 0; i < n; ++i) {
Entry<T, Object> entry = fields.getArrayEntryAt(i);
if (entry.getValue() instanceof GeneratedMessageLite) {
((GeneratedMessageLite<?, ?>) entry.getValue()).makeImmutable();
Expand Down Expand Up @@ -149,7 +150,8 @@ public FieldSet<T> clone() {
// We can't just call fields.clone because List objects in the map
// should not be shared.
FieldSet<T> clone = FieldSet.newFieldSet();
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
for (int i = 0; i < n; i++) {
Map.Entry<T, Object> entry = fields.getArrayEntryAt(i);
clone.setField(entry.getKey(), entry.getValue());
}
Expand Down Expand Up @@ -184,7 +186,8 @@ public Map<T, Object> getAllFields() {
private static <T extends FieldDescriptorLite<T>> SmallSortedMap<T, Object> cloneAllFieldsMap(
SmallSortedMap<T, Object> fields, boolean copyList, boolean resolveLazyFields) {
SmallSortedMap<T, Object> result = SmallSortedMap.newFieldMap();
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
for (int i = 0; i < n; i++) {
cloneFieldEntry(result, fields.getArrayEntryAt(i), copyList, resolveLazyFields);
}
for (Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
Expand Down Expand Up @@ -426,7 +429,8 @@ private static boolean isValidType(final WireFormat.FieldType type, final Object
* caller to check that all required fields are present.
*/
public boolean isInitialized() {
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
for (int i = 0; i < n; i++) {
if (!isInitialized(fields.getArrayEntryAt(i))) {
return false;
}
Expand Down Expand Up @@ -484,7 +488,8 @@ static int getWireFormatForFieldType(final WireFormat.FieldType type, boolean is

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

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

/** Like {@link #writeTo} but uses MessageSet wire format. */
public void writeMessageSetTo(final CodedOutputStream output) throws IOException {
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
for (int i = 0; i < n; i++) {
writeMessageSetTo(fields.getArrayEntryAt(i), output);
}
for (final Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
Expand Down Expand Up @@ -759,7 +766,8 @@ public static void writeField(
*/
public int getSerializedSize() {
int size = 0;
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
for (int i = 0; i < n; i++) {
final Map.Entry<T, Object> entry = fields.getArrayEntryAt(i);
size += computeFieldSize(entry.getKey(), entry.getValue());
}
Expand All @@ -772,7 +780,8 @@ public int getSerializedSize() {
/** Like {@link #getSerializedSize} but uses MessageSet wire format. */
public int getMessageSetSerializedSize() {
int size = 0;
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
for (int i = 0; i < n; i++) {
size += getMessageSetSerializedSize(fields.getArrayEntryAt(i));
}
for (final Map.Entry<T, Object> entry : fields.getOverflowEntries()) {
Expand Down Expand Up @@ -976,7 +985,8 @@ private FieldSet<T> buildImpl(boolean partial) {

private static <T extends FieldDescriptorLite<T>> void replaceBuilders(
SmallSortedMap<T, Object> fieldMap, boolean partial) {
for (int i = 0; i < fieldMap.getNumArrayEntries(); i++) {
int n = fieldMap.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
for (int i = 0; i < n; i++) {
replaceBuilders(fieldMap.getArrayEntryAt(i), partial);
}
for (Map.Entry<T, Object> entry : fieldMap.getOverflowEntries()) {
Expand Down Expand Up @@ -1268,7 +1278,8 @@ private void verifyType(final T descriptor, final Object value) {
* caller to check that all required fields are present.
*/
public boolean isInitialized() {
for (int i = 0; i < fields.getNumArrayEntries(); i++) {
int n = fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
for (int i = 0; i < n; i++) {
if (!FieldSet.isInitialized(fields.getArrayEntryAt(i))) {
return false;
}
Expand All @@ -1286,7 +1297,8 @@ public boolean isInitialized() {
*/
public void mergeFrom(final FieldSet<T> other) {
ensureIsMutable();
for (int i = 0; i < other.fields.getNumArrayEntries(); i++) {
int n = other.fields.getNumArrayEntries(); // Optimisation: hoist out of hot loop.
for (int i = 0; i < n; i++) {
mergeFromField(other.fields.getArrayEntryAt(i));
}
for (final Map.Entry<T, Object> entry : other.fields.getOverflowEntries()) {
Expand Down

0 comments on commit 229c958

Please sign in to comment.