Skip to content
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

Improve 4x performance of ContextManagerExtendService.createTraceCont… #698

Merged
merged 2 commits into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Release Notes.
* Support for tracing the callbacks of asynchronous methods in elasticsearch-6.x-plugin/elasticsearch-7.x-plugin.
* Fixed the invalid issue in the isInterface method in PluginFinder.
* Fix the opentracing toolkit SPI config
* Improve 4x performance of ContextManagerExtendService.createTraceContext()

All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/213?closed=1)

Expand Down
5 changes: 5 additions & 0 deletions apm-sniffer/apm-agent-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

package org.apache.skywalking.apm.agent.core.context;

import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.skywalking.apm.agent.core.boot.BootService;
import org.apache.skywalking.apm.agent.core.boot.DefaultImplementor;
import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
Expand All @@ -35,7 +38,7 @@
@DefaultImplementor
public class ContextManagerExtendService implements BootService, GRPCChannelListener {

private volatile String[] ignoreSuffixArray = new String[0];
private volatile Set ignoreSuffixSet;

private volatile GRPCChannelStatus status = GRPCChannelStatus.DISCONNECT;

Expand All @@ -50,7 +53,7 @@ public void prepare() {

@Override
public void boot() {
ignoreSuffixArray = Config.Agent.IGNORE_SUFFIX.split(",");
ignoreSuffixSet = Stream.of(Config.Agent.IGNORE_SUFFIX.split(",")).collect(Collectors.toSet());
ignoreSuffixPatternsWatcher = new IgnoreSuffixPatternsWatcher("agent.ignore_suffix", this);
spanLimitWatcher = new SpanLimitWatcher("agent.span_limit_per_segment");

Expand Down Expand Up @@ -82,8 +85,7 @@ public AbstractTracerContext createTraceContext(String operationName, boolean fo
}

int suffixIdx = operationName.lastIndexOf(".");
if (suffixIdx > -1 && Arrays.stream(ignoreSuffixArray)
.anyMatch(a -> a.equals(operationName.substring(suffixIdx)))) {
if (suffixIdx > -1 && ignoreSuffixSet.contains(operationName.substring(suffixIdx))) {
context = new IgnoredTracerContext();
} else {
SamplingService samplingService = ServiceManager.INSTANCE.findService(SamplingService.class);
Expand All @@ -104,7 +106,7 @@ public void statusChanged(final GRPCChannelStatus status) {

public void handleIgnoreSuffixPatternsChanged() {
if (StringUtil.isNotBlank(ignoreSuffixPatternsWatcher.getIgnoreSuffixPatterns())) {
ignoreSuffixArray = ignoreSuffixPatternsWatcher.getIgnoreSuffixPatterns().split(",");
ignoreSuffixSet = Stream.of(ignoreSuffixPatternsWatcher.getIgnoreSuffixPatterns().split(",")).collect(Collectors.toSet());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.skywalking.apm.agent.core.context;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.openjdk.jmh.runner.options.TimeValue;

import java.util.Arrays;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* ISSUE-12355
*/
@State(Scope.Benchmark)
@BenchmarkMode({Mode.Throughput, Mode.SampleTime})
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class IgnoreSuffixBenchmark {
public static String IGNORE_SUFFIX = ".jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg";
private String[] ignoreSuffixArray;
private Set ignoreSuffixSet;

private String operationName = "test.api";

@Setup
public void setup() {
ignoreSuffixArray = IGNORE_SUFFIX.split(",");
ignoreSuffixSet = Stream.of(ignoreSuffixArray).collect(Collectors.toSet());
}

@Benchmark
public boolean testArray() {
int suffixIdx = operationName.lastIndexOf(".");
return Arrays.stream(ignoreSuffixArray)
.anyMatch(a -> a.equals(operationName.substring(suffixIdx)));
}

@Benchmark
public boolean testHashSet() {
int suffixIdx = operationName.lastIndexOf(".");
return ignoreSuffixSet.contains(operationName.substring(suffixIdx));
}

public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(IgnoreSuffixBenchmark.class.getName())
.warmupIterations(3)
.warmupTime(TimeValue.seconds(10))
.measurementIterations(3)
.measurementTime(TimeValue.seconds(10))
.forks(1)
.build();
new Runner(opt).run();
}
/**
* # JMH version: 1.33
* # VM version: JDK 11.0.21, Java HotSpot(TM) 64-Bit Server VM, 11.0.21+9-LTS-193
* # VM invoker: /Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home/bin/java
* # VM options: -javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=60939:/Applications/IntelliJ IDEA CE.app/Contents/bin -Dfile.encoding=UTF-8
* # Blackhole mode: full + dont-inline hint (default, use -Djmh.blackhole.autoDetect=true to auto-detect)
* # Warmup: 3 iterations, 10 s each
* # Measurement: 3 iterations, 10 s each
* # Timeout: 10 min per iteration
* # Threads: 1 thread, will synchronize iterations
* # Benchmark mode: Sampling time
* # Benchmark: org.apache.skywalking.apm.agent.core.context.IgnoreSuffixBenchmark.testHashSet
*
* Benchmark Mode Cnt Score Error Units
* IgnoreSuffixBenchmark.testArray thrpt 3 0.007 ± 0.003 ops/ns
* IgnoreSuffixBenchmark.testHashSet thrpt 3 0.084 ± 0.035 ops/ns
* IgnoreSuffixBenchmark.testArray sample 823984 183.234 ± 11.201 ns/op
* IgnoreSuffixBenchmark.testArray:testArray·p0.00 sample 41.000 ns/op
* IgnoreSuffixBenchmark.testArray:testArray·p0.50 sample 166.000 ns/op
* IgnoreSuffixBenchmark.testArray:testArray·p0.90 sample 167.000 ns/op
* IgnoreSuffixBenchmark.testArray:testArray·p0.95 sample 209.000 ns/op
* IgnoreSuffixBenchmark.testArray:testArray·p0.99 sample 375.000 ns/op
* IgnoreSuffixBenchmark.testArray:testArray·p0.999 sample 1124.630 ns/op
* IgnoreSuffixBenchmark.testArray:testArray·p0.9999 sample 29971.248 ns/op
* IgnoreSuffixBenchmark.testArray:testArray·p1.00 sample 1130496.000 ns/op
* IgnoreSuffixBenchmark.testHashSet sample 972621 27.117 ± 1.788 ns/op
* IgnoreSuffixBenchmark.testHashSet:testHashSet·p0.00 sample ≈ 0 ns/op
* IgnoreSuffixBenchmark.testHashSet:testHashSet·p0.50 sample 41.000 ns/op
* IgnoreSuffixBenchmark.testHashSet:testHashSet·p0.90 sample 42.000 ns/op
* IgnoreSuffixBenchmark.testHashSet:testHashSet·p0.95 sample 42.000 ns/op
* IgnoreSuffixBenchmark.testHashSet:testHashSet·p0.99 sample 83.000 ns/op
* IgnoreSuffixBenchmark.testHashSet:testHashSet·p0.999 sample 167.000 ns/op
* IgnoreSuffixBenchmark.testHashSet:testHashSet·p0.9999 sample 6827.950 ns/op
* IgnoreSuffixBenchmark.testHashSet:testHashSet·p1.00 sample 478208.000 ns/op
*/
}
Loading