-
Notifications
You must be signed in to change notification settings - Fork 20
Performance Optimizations targeting to reduce CPU churn #73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2d37e47
d05a4a6
67a1149
03985ef
1d7e3ae
e603d1c
c2c8303
3f5f3b2
4f8932d
b6c6917
2451474
64dca6c
a41f8a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| // Copyright (c) 2020 Uber Technologies, Inc. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to deal | ||
| // in the Software without restriction, including without limitation the rights | ||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| // copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| // THE SOFTWARE. | ||
|
|
||
| package com.uber.m3.tally; | ||
|
|
||
| import com.uber.m3.util.Duration; | ||
| import com.uber.m3.util.ImmutableMap; | ||
| import org.openjdk.jmh.annotations.Benchmark; | ||
| import org.openjdk.jmh.annotations.BenchmarkMode; | ||
| import org.openjdk.jmh.annotations.Fork; | ||
| import org.openjdk.jmh.annotations.Mode; | ||
| import org.openjdk.jmh.annotations.OutputTimeUnit; | ||
| import org.openjdk.jmh.annotations.Setup; | ||
| import org.openjdk.jmh.annotations.State; | ||
| import org.openjdk.jmh.annotations.TearDown; | ||
|
|
||
| import java.util.Random; | ||
| import java.util.concurrent.TimeUnit; | ||
|
|
||
| @BenchmarkMode(Mode.Throughput) | ||
| @OutputTimeUnit(TimeUnit.MILLISECONDS) | ||
| @Fork(value = 2, jvmArgsAppend = { "-server", "-XX:+UseG1GC" }) | ||
| public class ScopeImplBenchmark { | ||
|
|
||
| private static final DurationBuckets EXPONENTIAL_BUCKETS = DurationBuckets.linear(Duration.ofMillis(1), Duration.ofMillis(10), 128); | ||
|
|
||
| private static final String[] COUNTER_NAMES = { | ||
| "first-counter", | ||
| "second-counter", | ||
| "third-counter", | ||
| "fourth-counter", | ||
| "fifth-counter", | ||
| }; | ||
|
|
||
| private static final String[] GAUGE_NAMES = { | ||
| "first-gauge", | ||
| "second-gauge", | ||
| "third-gauge", | ||
| "fourth-gauge", | ||
| "fifth-gauge", | ||
| }; | ||
|
|
||
| private static final String[] HISTOGRAM_NAMES = { | ||
| "first-histogram", | ||
| "second-histogram", | ||
| "third-histogram", | ||
| "fourth-histogram", | ||
| "fifth-histogram", | ||
| }; | ||
|
|
||
| @Benchmark | ||
| public void scopeReportingBenchmark(BenchmarkState state) { | ||
| state.scope.reportLoopIteration(); | ||
| } | ||
|
|
||
| @State(org.openjdk.jmh.annotations.Scope.Benchmark) | ||
| public static class BenchmarkState { | ||
|
|
||
| private ScopeImpl scope; | ||
|
|
||
| @Setup | ||
| public void setup() { | ||
| this.scope = | ||
| (ScopeImpl) new RootScopeBuilder() | ||
| .reporter(new TestStatsReporter()) | ||
| .tags( | ||
| ImmutableMap.of( | ||
| "service", "some-service", | ||
| "application", "some-application", | ||
| "instance", "some-instance" | ||
| ) | ||
| ) | ||
| .reportEvery(Duration.MAX_VALUE); | ||
|
|
||
| for (String counterName : COUNTER_NAMES) { | ||
| scope.counter(counterName).inc(1); | ||
| } | ||
|
|
||
| for (String gaugeName : GAUGE_NAMES) { | ||
| scope.gauge(gaugeName).update(0.); | ||
| } | ||
|
|
||
| for (String histogramName : HISTOGRAM_NAMES) { | ||
| Histogram h = scope.histogram(histogramName, EXPONENTIAL_BUCKETS); | ||
|
|
||
| Random r = new Random(); | ||
|
|
||
| // Populate at least 20% of the buckets | ||
| int bucketsCount = EXPONENTIAL_BUCKETS.buckets.size(); | ||
| for (int i = 0; i < bucketsCount / 5; ++i) { | ||
| h.recordDuration(EXPONENTIAL_BUCKETS.buckets.get(r.nextInt(bucketsCount))); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @TearDown | ||
| public void teardown() { | ||
| scope.close(); | ||
| } | ||
|
|
||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,15 +27,24 @@ | |
| /** | ||
| * Default implementation of a {@link Counter}. | ||
| */ | ||
| class CounterImpl implements Counter { | ||
| class CounterImpl extends MetricBase implements Counter { | ||
| private AtomicLong prev = new AtomicLong(0); | ||
| private AtomicLong curr = new AtomicLong(0); | ||
|
|
||
| protected CounterImpl(String fqn) { | ||
| super(fqn); | ||
| } | ||
|
|
||
| @Override | ||
| public void inc(long delta) { | ||
| curr.getAndAdd(delta); | ||
| } | ||
|
|
||
| @Override | ||
|
||
| public String getQualifiedName() { | ||
| return super.getQualifiedName(); | ||
| } | ||
|
|
||
| long value() { | ||
| long current = curr.get(); | ||
| long previous = prev.get(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| // Copyright (c) 2020 Uber Technologies, Inc. | ||
| // | ||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| // of this software and associated documentation files (the "Software"), to deal | ||
| // in the Software without restriction, including without limitation the rights | ||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| // copies of the Software, and to permit persons to whom the Software is | ||
| // furnished to do so, subject to the following conditions: | ||
| // | ||
| // The above copyright notice and this permission notice shall be included in | ||
| // all copies or substantial portions of the Software. | ||
| // | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| // THE SOFTWARE. | ||
|
|
||
| package com.uber.m3.tally; | ||
|
|
||
| import com.uber.m3.util.ImmutableMap; | ||
|
|
||
| abstract class MetricBase { | ||
|
|
||
| private final String fullyQualifiedName; | ||
|
|
||
| protected MetricBase(String fqn) { | ||
| this.fullyQualifiedName = fqn; | ||
| } | ||
|
|
||
| String getQualifiedName() { | ||
| return fullyQualifiedName; | ||
| } | ||
|
|
||
| abstract void report(String name, ImmutableMap<String, String> tags, StatsReporter reporter); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why comment this out? i'd prefer if you either add in or remove entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is cleaned up in #74