diff --git a/build.gradle b/build.gradle index c71c2377b..db3e4df8f 100755 --- a/build.gradle +++ b/build.gradle @@ -113,7 +113,7 @@ subprojects { profilers = ['stack', 'gc'] includeTests = false duplicateClassesStrategy = DuplicatesStrategy.WARN - includes = ['.*Caching.*'] + includes = ['.*PercentileTimers.*'] } checkstyle { diff --git a/spectator-api/src/main/java/com/netflix/spectator/api/histogram/PercentileDistributionSummary.java b/spectator-api/src/main/java/com/netflix/spectator/api/histogram/PercentileDistributionSummary.java index e85d24e40..8620a7385 100644 --- a/spectator-api/src/main/java/com/netflix/spectator/api/histogram/PercentileDistributionSummary.java +++ b/spectator-api/src/main/java/com/netflix/spectator/api/histogram/PercentileDistributionSummary.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 Netflix, Inc. + * Copyright 2014-2024 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,6 @@ import com.netflix.spectator.api.Measurement; import com.netflix.spectator.api.Registry; import com.netflix.spectator.api.Statistic; -import com.netflix.spectator.api.Utils; import com.netflix.spectator.api.patterns.IdBuilder; import com.netflix.spectator.api.patterns.TagsBuilder; @@ -66,8 +65,20 @@ public final class PercentileDistributionSummary implements DistributionSummary */ private static PercentileDistributionSummary computeIfAbsent( Registry registry, Id id, long min, long max) { - Object summary = Utils.computeIfAbsent( - registry.state(), id, i -> new PercentileDistributionSummary(registry, id, min, max)); + // Inlined: + // Object summary = Utils.computeIfAbsent( + // registry.state(), id, i -> new PercentileDistributionSummary(registry, id, min, max)); + // + // The lambda needs to capture the parameters for registry, min, and max which can lead to + // a high allocation rate for the lambda instance. + Object summary = registry.state().get(id); + if (summary == null) { + PercentileDistributionSummary newSummary = new PercentileDistributionSummary(registry, id, min, max); + summary = registry.state().putIfAbsent(id, newSummary); + if (summary == null) { + return newSummary; + } + } return (summary instanceof PercentileDistributionSummary) ? ((PercentileDistributionSummary) summary).withRange(min, max) : new PercentileDistributionSummary(registry, id, min, max); diff --git a/spectator-api/src/main/java/com/netflix/spectator/api/histogram/PercentileTimer.java b/spectator-api/src/main/java/com/netflix/spectator/api/histogram/PercentileTimer.java index 960890107..4471a78c4 100644 --- a/spectator-api/src/main/java/com/netflix/spectator/api/histogram/PercentileTimer.java +++ b/spectator-api/src/main/java/com/netflix/spectator/api/histogram/PercentileTimer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2023 Netflix, Inc. + * Copyright 2014-2024 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import com.netflix.spectator.api.Registry; import com.netflix.spectator.api.Statistic; import com.netflix.spectator.api.Timer; -import com.netflix.spectator.api.Utils; import com.netflix.spectator.api.patterns.IdBuilder; import com.netflix.spectator.api.patterns.TagsBuilder; @@ -72,8 +71,20 @@ public final class PercentileTimer implements Timer { * site. */ private static PercentileTimer computeIfAbsent(Registry registry, Id id, long min, long max) { - Object timer = Utils.computeIfAbsent( - registry.state(), id, i -> new PercentileTimer(registry, id, min, max)); + // Inlined: + // Object timer = Utils.computeIfAbsent( + // registry.state(), id, i -> new PercentileTimer(registry, id, min, max)); + // + // The lambda needs to capture the parameters for registry, min, and max which can lead to + // a high allocation rate for the lambda instance. + Object timer = registry.state().get(id); + if (timer == null) { + PercentileTimer newTimer = new PercentileTimer(registry, id, min, max); + timer = registry.state().putIfAbsent(id, newTimer); + if (timer == null) { + return newTimer; + } + } return (timer instanceof PercentileTimer) ? ((PercentileTimer) timer).withRange(min, max) : new PercentileTimer(registry, id, min, max);