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