Add JMH Benchmarks
ADD
dd-java-agent/benchmark/benchmark.gradle
+plugins {
+ id "me.champeau.gradle.jmh" version "0.4.4"
+}
+
+apply from: "${rootDir}/gradle/java.gradle"
+
+dependencies {
+ jmh project(':dd-trace-annotations')
+ jmh group: 'net.bytebuddy', name: 'byte-buddy-agent', version: '1.7.6'
+}
+
+configurations.testRuntimeClasspath.dependencies.clear()
+
+
+jmh {
+ timeUnit = 'us' // Output time unit. Available time units are: [m, s, ms, us, ns].
+ benchmarkMode = ['thrpt', 'avgt']
+ timeOnIteration = '1s'
+ iterations = 1 // Number of measurement iterations to do.
+ fork = 2 // How many times to forks a single benchmark. Use 0 to disable forking altogether
+// jvmArgs = ["-Dasdf=123"]
+// jvmArgs = ["-javaagent:${project(':dd-java-agent').shadowJar.archivePath}"]
+ failOnError = true // Should JMH fail immediately if any benchmark had experienced the unrecoverable error?
+ warmup = '2s' // Time to spend at each warmup iteration.
+ warmupIterations = 1 // Number of warmup iterations to do.
+// warmupForks = 0 // How many warmup forks to make for a single benchmark. 0 to disable warmup forks.
+
+// profilers = ['stack']
+ // Use profilers to collect additional data. Supported profilers: [cl, comp, gc, stack, perf, perfnorm, perfasm, xperf, xperfasm, hs_cl, hs_comp, hs_gc, hs_rt, hs_thr]
+
+// humanOutputFile = project.file("${project.buildDir}/reports/jmh/human.txt") // human-readable output file
+// operationsPerInvocation = 10 // Operations per invocation.
+// synchronizeIterations = false // Synchronize iterations?
+// timeout = '1s' // Timeout for benchmark iteration.
+ includeTests = false
+ // Allows to include test sources into generate JMH jar, i.e. use it when benchmarks depend on the test classes.
+
+ duplicateClassesStrategy = 'fail'
+ jmhVersion = '1.19' // Specifies JMH version
+}
+
+// configured as a separate task since the 'jmh' task did not like adding a javaagent argument.
+task jmhAgent(type: JavaExec, dependsOn: project.tasks.jmhCompileGeneratedClasses) {
+ classpath = files(project.jmhCompileGeneratedClasses.destinationDir)
+ classpath += sourceSets.jmh.runtimeClasspath
+ main = "org.openjdk.jmh.Main"
+ args += ["-tu", "us"]
+ args += ["-bm", "avgt"]
+ args += ["-r", "1s"]
+ args += ["-i", "1"]
+ args += ["-f", "2"]
+ args += ["-foe", "true"]
+ args += ["-w", "2s"]
+ args += ["-wi", "1"]
+// jvmArgs = ["-javaagent:${project(':dd-java-agent').shadowJar.archivePath}"]
+}
+
+tasks.jmhAgent.dependsOn project(':dd-java-agent').shadowJar
+

ADD
dd-java-agent/benchmark/src/jmh/java/com/datadoghq/agent/ClassRetransformingBenchmark.java
+package com.datadoghq.agent;
+
+import com.datadoghq.trace.Trace;
+import java.lang.instrument.Instrumentation;
+import java.lang.instrument.UnmodifiableClassException;
+import net.bytebuddy.agent.ByteBuddyAgent;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+public class ClassRetransformingBenchmark {
+
+ @State(Scope.Benchmark)
+ public static class BenchmarkState {
+ private final Instrumentation inst = ByteBuddyAgent.install();
+ }
+
+ @Benchmark
+ public void testIgnoredRetransform(final BenchmarkState state) throws UnmodifiableClassException {
+ state.inst.retransformClasses(Object.class);
+ }
+
+ @Benchmark
+ public void testSimpleRetransform(final BenchmarkState state) throws UnmodifiableClassException {
+ state.inst.retransformClasses(SimpleClass.class);
+ }
+
+ @Benchmark
+ public void testDeepRetransform(final BenchmarkState state) throws UnmodifiableClassException {
+ state.inst.retransformClasses(DeepClass.class);
+ }
+
+ public static class SimpleClass {
+ @Trace
+ public void aMethodToTrace() {}
+ }
+
+ public static interface A {
+ @Trace
+ void interfaceTrace();
+ }
+
+ public static interface B extends A {
+ void something();
+ }
+
+ public static interface C extends B {
+ void somethingElse();
+ }
+
+ public static class DeepClass implements C {
+
+ @Override
+ public void interfaceTrace() {}
+
+ @Override
+ public void something() {}
+
+ @Override
+ public void somethingElse() {}
+ }
+}

MODIFY
gradle/dependencies.gradle
gradle/dependencies.gradle
+def groovyVer = GroovySystem.version
+def spockGroovyVer = GroovySystem.version.replaceAll(/\.\d+$/, '')
+
ext {
version = [
opentracing: '0.30.0',
@@ -6,8 +9,8 @@ ext {
guava : "21.0",
jackson : "2.8.7",
- spock : "1.0-groovy-2.4",
- groovy : "2.4.11",
+ spock : "1.0-groovy-$spockGroovyVer",
+ groovy : groovyVer,
junit : "4.12",
logback : "1.2.3",
]

MODIFY
settings.gradle
settings.gradle
@@ -2,6 +2,7 @@ rootProject.name = 'dd-trace-java'
include ':dd-trace'
include ':dd-java-agent'
+include ':dd-java-agent:benchmark'
include ':dd-java-agent:tooling'
include ':dd-java-agent-ittests'
include ':dd-trace-examples:async-tracing'

Add JMH Benchmarks