From e41a9dfa69488e3cecb2766dcd2d6a65c884a00b Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Wed, 7 Aug 2024 15:45:40 -0500 Subject: [PATCH] Avoid allocations when advice doesn't remove any attributes --- .../view/AdviceAttributesProcessor.java | 17 +++++++++++++++++ .../view/AdviceAttributesProcessorTest.java | 13 +++++++++++++ 2 files changed, 30 insertions(+) diff --git a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java index 161dcd72832..b0373f25765 100644 --- a/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java +++ b/sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessor.java @@ -23,11 +23,28 @@ final class AdviceAttributesProcessor extends AttributesProcessor { @Override public Attributes process(Attributes incoming, Context context) { + // Exit early to avoid allocations if the incoming attributes do not have extra keys to be + // filtered + if (!hasExtraKeys(incoming)) { + return incoming; + } AttributesBuilder builder = incoming.toBuilder(); builder.removeIf(key -> !attributeKeys.contains(key)); return builder.build(); } + /** Returns true if {@code attributes} has keys not contained in {@link #attributeKeys}. */ + private boolean hasExtraKeys(Attributes attributes) { + boolean[] result = {false}; + attributes.forEach( + (key, value) -> { + if (!result[0] && !attributeKeys.contains(key)) { + result[0] = true; + } + }); + return result[0]; + } + @Override public boolean usesContext() { return false; diff --git a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessorTest.java b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessorTest.java index 294c05ea157..d809c8a3794 100644 --- a/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessorTest.java +++ b/sdk/metrics/src/test/java/io/opentelemetry/sdk/metrics/internal/view/AdviceAttributesProcessorTest.java @@ -24,6 +24,19 @@ void doesNotUseContext() { assertThat(new AdviceAttributesProcessor(emptyList()).usesContext()).isFalse(); } + @Test + void noExtraAttributes() { + AttributesProcessor processor = + new AdviceAttributesProcessor(asList(stringKey("abc"), stringKey("def"))); + + Attributes result = + processor.process( + Attributes.builder().put(stringKey("abc"), "abc").put(stringKey("def"), "def").build(), + Context.root()); + + assertThat(result).containsOnly(entry(stringKey("abc"), "abc"), entry(stringKey("def"), "def")); + } + @Test void removeUnwantedAttributes() { AttributesProcessor processor =