• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2021. Uber Technologies
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *    http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16plugins {
17    id 'java-library'
18    id 'nullaway.java-test-conventions'
19    id 'me.champeau.jmh'
20}
21
22configurations {
23    // create a configuration for the sources and dependencies of each benchmark
24    caffeineSources
25    caffeineDeps
26
27    autodisposeSources
28    autodisposeDeps
29
30    nullawayReleaseSources
31    nullawayReleaseDeps
32    nullawayReleaseProcessors
33}
34dependencies {
35
36    // Add NullAway and Error Prone Core as dependencies.  This ensures that the classes get included
37    // in the jmh-generated jar, and hence get JIT-compiled during benchmarking.  Without this dependence, NullAway
38    // can still be loaded via the processor path, but it gets reloaded on each run of compilation, skewing
39    // performance measurements
40    implementation project(':nullaway')
41    // use the same version of Error Prone Core that we are compiling NullAway against, so we can
42    // benchmark against different versions of Error Prone
43    implementation deps.build.errorProneCoreForApi
44
45
46    // Source jars for our desired benchmarks
47    caffeineSources('com.github.ben-manes.caffeine:caffeine:3.0.2:sources') {
48        transitive = false
49    }
50    autodisposeSources('com.uber.autodispose2:autodispose:2.1.0:sources') {
51        transitive = false
52    }
53    nullawayReleaseSources('com.uber.nullaway:nullaway:0.9.7:sources') {
54        transitive = false
55    }
56
57    caffeineDeps 'com.github.ben-manes.caffeine:caffeine:3.0.2'
58    autodisposeDeps 'com.uber.autodispose2:autodispose:2.1.0'
59    nullawayReleaseDeps 'com.uber.nullaway:nullaway:0.9.7'
60    // Add in the compile-only dependencies of NullAway
61    // Use fixed versions here since we are compiling a particular version of NullAway
62    nullawayReleaseDeps "com.google.errorprone:error_prone_core:2.13.1"
63    nullawayReleaseDeps "com.facebook.infer.annotation:infer-annotation:0.11.0"
64    nullawayReleaseDeps "org.jetbrains:annotations:13.0"
65
66    // To run AutoValue during NullAway compilation
67    nullawayReleaseProcessors "com.google.auto.value:auto-value:1.9"
68
69    testImplementation deps.test.junit4
70}
71
72def caffeineSourceDir = project.layout.buildDirectory.dir('caffeineSources')
73def autodisposeSourceDir = project.layout.buildDirectory.dir('autodisposeSources')
74def nullawayReleaseSourceDir = project.layout.buildDirectory.dir('nullawayReleaseSources')
75
76task extractCaffeineSources(type: Copy) {
77    from zipTree(configurations.caffeineSources.singleFile)
78    into caffeineSourceDir
79}
80
81task extractAutodisposeSources(type: Copy) {
82    from zipTree(configurations.autodisposeSources.singleFile)
83    into autodisposeSourceDir
84}
85
86task extractNullawayReleaseSources(type: Copy) {
87    from zipTree(configurations.nullawayReleaseSources.singleFile)
88    into nullawayReleaseSourceDir
89}
90
91compileJava.dependsOn(extractCaffeineSources)
92compileJava.dependsOn(extractAutodisposeSources)
93compileJava.dependsOn(extractNullawayReleaseSources)
94
95// always run jmh
96tasks.getByName('jmh').outputs.upToDateWhen { false }
97
98// a trick: to get the classpath for a benchmark, create a configuration that depends on the benchmark, and
99// then filter out the benchmark itself
100def caffeineClasspath = configurations.caffeineDeps.filter({f -> !f.toString().contains("caffeine-3.0.2")}).asPath
101def autodisposeClasspath = configurations.autodisposeDeps.filter({f -> !f.toString().contains("autodispose-2.1.0")}).asPath
102def nullawayReleaseClasspath = configurations.nullawayReleaseDeps.filter({f -> !f.toString().contains("nullaway-0.9.7")}).asPath
103
104def nullawayReleaseProcessorpath = configurations.nullawayReleaseProcessors.asPath
105
106// Extra JVM arguments to expose relevant paths for compiling benchmarks
107def extraJVMArgs = [
108    "-Dnullaway.caffeine.sources=${caffeineSourceDir.get()}",
109    "-Dnullaway.caffeine.classpath=$caffeineClasspath",
110    "-Dnullaway.autodispose.sources=${autodisposeSourceDir.get()}",
111    "-Dnullaway.autodispose.classpath=$autodisposeClasspath",
112    "-Dnullaway.nullawayRelease.sources=${nullawayReleaseSourceDir.get()}",
113    "-Dnullaway.nullawayRelease.classpath=$nullawayReleaseClasspath",
114    "-Dnullaway.nullawayRelease.processorpath=$nullawayReleaseProcessorpath",
115]
116
117jmh {
118    // seems we need more iterations to fully warm up the JIT
119    warmupIterations = 10
120
121
122    jvmArgsAppend = extraJVMArgs
123
124    // commented-out examples of how to tweak other jmh parameters; they show the default values
125    // for more examples see https://github.com/melix/jmh-gradle-plugin/blob/master/README.adoc#configuration-options
126    // iterations = 5
127    // fork = 5
128    // includes = ['DFlowMicro']
129}
130
131tasks.named('test') {
132    // pass the extra JVM args so we can compile benchmarks in unit tests
133    jvmArgs += extraJVMArgs
134}
135
136tasks.getByName('testJdk21').configure {
137    jvmArgs += extraJVMArgs
138}
139