/* * Copyright (C) 2021. Uber Technologies * * Licensed 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. */ plugins { id 'java-library' id 'nullaway.java-test-conventions' id 'me.champeau.jmh' } configurations { // create a configuration for the sources and dependencies of each benchmark caffeineSources caffeineDeps autodisposeSources autodisposeDeps nullawayReleaseSources nullawayReleaseDeps nullawayReleaseProcessors } dependencies { // Add NullAway and Error Prone Core as dependencies. This ensures that the classes get included // in the jmh-generated jar, and hence get JIT-compiled during benchmarking. Without this dependence, NullAway // can still be loaded via the processor path, but it gets reloaded on each run of compilation, skewing // performance measurements implementation project(':nullaway') // use the same version of Error Prone Core that we are compiling NullAway against, so we can // benchmark against different versions of Error Prone implementation deps.build.errorProneCoreForApi // Source jars for our desired benchmarks caffeineSources('com.github.ben-manes.caffeine:caffeine:3.0.2:sources') { transitive = false } autodisposeSources('com.uber.autodispose2:autodispose:2.1.0:sources') { transitive = false } nullawayReleaseSources('com.uber.nullaway:nullaway:0.9.7:sources') { transitive = false } caffeineDeps 'com.github.ben-manes.caffeine:caffeine:3.0.2' autodisposeDeps 'com.uber.autodispose2:autodispose:2.1.0' nullawayReleaseDeps 'com.uber.nullaway:nullaway:0.9.7' // Add in the compile-only dependencies of NullAway // Use fixed versions here since we are compiling a particular version of NullAway nullawayReleaseDeps "com.google.errorprone:error_prone_core:2.13.1" nullawayReleaseDeps "com.facebook.infer.annotation:infer-annotation:0.11.0" nullawayReleaseDeps "org.jetbrains:annotations:13.0" // To run AutoValue during NullAway compilation nullawayReleaseProcessors "com.google.auto.value:auto-value:1.9" testImplementation deps.test.junit4 } def caffeineSourceDir = project.layout.buildDirectory.dir('caffeineSources') def autodisposeSourceDir = project.layout.buildDirectory.dir('autodisposeSources') def nullawayReleaseSourceDir = project.layout.buildDirectory.dir('nullawayReleaseSources') task extractCaffeineSources(type: Copy) { from zipTree(configurations.caffeineSources.singleFile) into caffeineSourceDir } task extractAutodisposeSources(type: Copy) { from zipTree(configurations.autodisposeSources.singleFile) into autodisposeSourceDir } task extractNullawayReleaseSources(type: Copy) { from zipTree(configurations.nullawayReleaseSources.singleFile) into nullawayReleaseSourceDir } compileJava.dependsOn(extractCaffeineSources) compileJava.dependsOn(extractAutodisposeSources) compileJava.dependsOn(extractNullawayReleaseSources) // always run jmh tasks.getByName('jmh').outputs.upToDateWhen { false } // a trick: to get the classpath for a benchmark, create a configuration that depends on the benchmark, and // then filter out the benchmark itself def caffeineClasspath = configurations.caffeineDeps.filter({f -> !f.toString().contains("caffeine-3.0.2")}).asPath def autodisposeClasspath = configurations.autodisposeDeps.filter({f -> !f.toString().contains("autodispose-2.1.0")}).asPath def nullawayReleaseClasspath = configurations.nullawayReleaseDeps.filter({f -> !f.toString().contains("nullaway-0.9.7")}).asPath def nullawayReleaseProcessorpath = configurations.nullawayReleaseProcessors.asPath // Extra JVM arguments to expose relevant paths for compiling benchmarks def extraJVMArgs = [ "-Dnullaway.caffeine.sources=${caffeineSourceDir.get()}", "-Dnullaway.caffeine.classpath=$caffeineClasspath", "-Dnullaway.autodispose.sources=${autodisposeSourceDir.get()}", "-Dnullaway.autodispose.classpath=$autodisposeClasspath", "-Dnullaway.nullawayRelease.sources=${nullawayReleaseSourceDir.get()}", "-Dnullaway.nullawayRelease.classpath=$nullawayReleaseClasspath", "-Dnullaway.nullawayRelease.processorpath=$nullawayReleaseProcessorpath", ] jmh { // seems we need more iterations to fully warm up the JIT warmupIterations = 10 jvmArgsAppend = extraJVMArgs // commented-out examples of how to tweak other jmh parameters; they show the default values // for more examples see https://github.com/melix/jmh-gradle-plugin/blob/master/README.adoc#configuration-options // iterations = 5 // fork = 5 // includes = ['DFlowMicro'] } tasks.named('test') { // pass the extra JVM args so we can compile benchmarks in unit tests jvmArgs += extraJVMArgs } tasks.getByName('testJdk21').configure { jvmArgs += extraJVMArgs }