-
Notifications
You must be signed in to change notification settings - Fork 19
Adding Sanitizer interface and implementation #97
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
base: master
Are you sure you want to change the base?
Changes from all commits
0f77624
afa6c6d
a772d57
a188eee
fc8f1aa
edc0a4e
d8fdac9
45243d8
a27e6d3
5aa1dc5
1b941ff
6e4f04a
5328ba1
5cb9f0f
3e34116
dde5ff4
fbbf111
f1d8f25
bb561ec
315c559
d0c33f8
08ed2d5
8b09947
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,4 @@ | ||
| Benchmark Mode Cnt Score Error Units | ||
| ScopeImplBenchmark.recordingBenchmark thrpt 10 74.819 ± 4.573 ops/ms | ||
| ScopeImplBenchmark.recordingWithSanitizingDashBenchmark thrpt 10 49.256 ± 9.474 ops/ms | ||
| ScopeImplBenchmark.scopeReportingBenchmark thrpt 10 39066.800 ± 262.844 ops/ms | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,23 +20,18 @@ | |
|
|
||
| package com.uber.m3.tally; | ||
|
|
||
| import com.uber.m3.tally.sanitizers.ScopeSanitizerBuilder; | ||
| import com.uber.m3.tally.sanitizers.ValidCharacters; | ||
| 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 org.openjdk.jmh.annotations.*; | ||
|
|
||
| import java.util.Random; | ||
| import java.util.concurrent.TimeUnit; | ||
|
|
||
| @BenchmarkMode(Mode.Throughput) | ||
| @OutputTimeUnit(TimeUnit.MILLISECONDS) | ||
| @Fork(value = 2, jvmArgsAppend = { "-server", "-XX:+UseG1GC" }) | ||
| @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); | ||
|
|
@@ -67,28 +62,56 @@ public class ScopeImplBenchmark { | |
|
|
||
| @Benchmark | ||
| public void scopeReportingBenchmark(BenchmarkState state) { | ||
| state.scope.reportLoopIteration(); | ||
| state.reportingBenchmarkScope.reportLoopIteration(); | ||
| } | ||
|
|
||
| @Benchmark | ||
| public void recordingWithSanitizingDashBenchmark(BenchmarkState state) { | ||
| state.recordTestMetrics(state.sanitizingBenchmarkScope); | ||
| } | ||
|
|
||
| @Benchmark | ||
| public void recordingBenchmark(BenchmarkState state) { | ||
| state.recordTestMetrics(state.recordingBenchmarkScope); | ||
| } | ||
|
|
||
| @State(org.openjdk.jmh.annotations.Scope.Benchmark) | ||
| public static class BenchmarkState { | ||
|
|
||
| private ScopeImpl scope; | ||
| private ScopeImpl reportingBenchmarkScope; | ||
| private ScopeImpl sanitizingBenchmarkScope; | ||
| private ScopeImpl recordingBenchmarkScope; | ||
|
|
||
| @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); | ||
| final ScopeBuilder scopeBuilder = new RootScopeBuilder() | ||
| .reporter(new TestStatsReporter()) | ||
| .tags( | ||
| ImmutableMap.of( | ||
| "service", "some-service", | ||
| "application", "some-application", | ||
| "instance", "some-instance" | ||
| ) | ||
| ); | ||
|
|
||
| this.reportingBenchmarkScope = | ||
| (ScopeImpl) scopeBuilder.reportEvery(Duration.MAX_VALUE); | ||
|
|
||
| this.recordTestMetrics(this.reportingBenchmarkScope); | ||
|
|
||
| this.recordingBenchmarkScope = (ScopeImpl) scopeBuilder.reportEvery(Duration.MAX_VALUE); | ||
| this.sanitizingBenchmarkScope = | ||
| (ScopeImpl) scopeBuilder.sanitizer( | ||
| new ScopeSanitizerBuilder() | ||
| .withNameValidCharacters(ValidCharacters.of(null, ValidCharacters.UNDERSCORE_CHARACTERS)) | ||
| .withTagKeyValidCharacters(ValidCharacters.of(null, ValidCharacters.UNDERSCORE_CHARACTERS)) | ||
| .withTagValueValidCharacters(ValidCharacters.of(null, ValidCharacters.UNDERSCORE_CHARACTERS)) | ||
| .build() | ||
| ) | ||
| .reportEvery(Duration.MAX_VALUE); | ||
| } | ||
|
|
||
| public void recordTestMetrics(final ScopeImpl scope) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is a good routine to check -- this was used as pre-init seq, and i would suggest to keep it as such. Instead create separate benchmarks and routines to update counter/gauge/histogram separately.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as my pervious response. I appreciate your time reviewing and commenting it.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please check my comment above. We're more than happy to help w/ guidance, but benchmarking is now a standard requirement from non-trivial contributions.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, will revert that one back. Can you give me details about what you want to benchmark? -- which method/function/routines?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As i have called out prior, let's test creation and recording fro each type of metric individually (counter/gauge/histogram). |
||
| for (String counterName : COUNTER_NAMES) { | ||
| scope.counter(counterName).inc(1); | ||
| } | ||
|
|
@@ -112,7 +135,9 @@ public void setup() { | |
|
|
||
| @TearDown | ||
| public void teardown() { | ||
| scope.close(); | ||
| reportingBenchmarkScope.close(); | ||
| recordingBenchmarkScope.close(); | ||
| sanitizingBenchmarkScope.close(); | ||
| } | ||
|
|
||
| } | ||
|
|
||
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.
Please check how other benchmarks are reported (we need to capture all data-points offered by JMH)
Uh oh!
There was an error while loading. Please reload this page.
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.
Sorry, I don't really understand how exactly to do it.
Would you mind taking it over? I am not convinced that this should be done by this PR, as the benchmark is already missing. The most problem is I don't have a clear picture of what you really want for benchmarking(with out detailed documentation), and it should be much easier if your team just do it.
LMK if you agree.
Uh oh!
There was an error while loading. Please reload this page.
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.
It should be done by this PR. This is a critical library laying in the hot-path of execution of many services, hence we need to maintain the focus on its performance.
Over the last year a lot of efforts have been put in to optimize, streamline, and make this library robust to serve the needs it was originally built for. Therefore, as a new contribution guideline we require any non-trivial change to adhere to the same basic principles of assuring library's correctness and performance.
Totally appreciate the amount of incremental effort that is required to adhere to this heightened standards from every contribution, but unfortunately there's no other way to guarantee high-level of reliability and performance of the open-source library otherwise.
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.
Can you give more details here? I did check but don't know how that works(though I see other reports have the details like gc time).
For example another benchmark is just
public class M3ReporterBenchmark extends AbstractReporterBenchmark. So I don't know what am I missing here.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.
@SokolAndrey can you help in here?