From 75b835d92925d0e80a12eaa7975f00c12c5ee767 Mon Sep 17 00:00:00 2001 From: Yury Yarashevich Date: Mon, 3 Feb 2025 23:28:42 +0100 Subject: [PATCH] Cache hash code of immutable values of type Tags & KeyValues --- .../java/io/micrometer/common/KeyValues.java | 18 +++++++++++++++--- .../io/micrometer/core/instrument/Tags.java | 18 +++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/micrometer-commons/src/main/java/io/micrometer/common/KeyValues.java b/micrometer-commons/src/main/java/io/micrometer/common/KeyValues.java index 6c32e8f878..ca2f0921bc 100644 --- a/micrometer-commons/src/main/java/io/micrometer/common/KeyValues.java +++ b/micrometer-commons/src/main/java/io/micrometer/common/KeyValues.java @@ -51,6 +51,11 @@ public final class KeyValues implements Iterable { */ private final int length; + /** + * Cache the hash code of the {@code KeyValues}, 0 value means hash was not computed. + */ + private int hash; + /** * A constructor that initializes a {@code KeyValues} object with a sorted set of * key-values and its length. @@ -291,9 +296,16 @@ public Stream stream() { @Override public int hashCode() { - int result = 1; - for (int i = 0; i < length; i++) { - result = 31 * result + sortedSet[i].hashCode(); + int result = hash; + if (result == 0) { + result = 1; + for (int i = 0; i < length; i++) { + result = 31 * result + sortedSet[i].hashCode(); + } + if (result == 0) { // Re-map 0 hash code + result = 1; + } + hash = result; } return result; } diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/Tags.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/Tags.java index 1c696066e8..014bbd1441 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/Tags.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/Tags.java @@ -48,6 +48,11 @@ public final class Tags implements Iterable { */ private final int length; + /** + * Cache the hash code of the {@code Tags}, 0 value means hash was not computed. + */ + private int hash; + /** * A constructor that initializes a {@code Tags} object with a sorted set of tags and * its length. @@ -267,9 +272,16 @@ public Stream stream() { @Override public int hashCode() { - int result = 1; - for (int i = 0; i < length; i++) { - result = 31 * result + sortedSet[i].hashCode(); + int result = hash; + if (result == 0) { + result = 1; + for (int i = 0; i < length; i++) { + result = 31 * result + sortedSet[i].hashCode(); + } + if (result == 0) { // Re-map 0 hash code + result = 1; + } + hash = result; } return result; }