Pass current Kotlin version to benchmark script

Allows using different current Kotlin versions in benchmark.
For example, SNAPSHOT version when current branch is master and
dev version on CI build.

^KT-49921 In Progress
This commit is contained in:
Yahor Berdnikau
2021-12-22 12:37:01 +01:00
parent ba201a249e
commit 10a1d2ca1d
5 changed files with 45 additions and 16 deletions
@@ -18,6 +18,7 @@ import org.jetbrains.kotlinx.dataframe.io.toHTML
import org.jetbrains.kotlinx.dataframe.io.writeCSV import org.jetbrains.kotlinx.dataframe.io.writeCSV
import org.jetbrains.kotlinx.dataframe.math.median import org.jetbrains.kotlinx.dataframe.math.median
import java.io.File import java.io.File
import java.io.InputStream
import java.util.zip.ZipInputStream import java.util.zip.ZipInputStream
import kotlin.reflect.typeOf import kotlin.reflect.typeOf
import kotlin.script.experimental.annotations.KotlinScript import kotlin.script.experimental.annotations.KotlinScript
@@ -37,6 +38,7 @@ abstract class BenchmarkTemplate(
private val gitCommitSha: String, private val gitCommitSha: String,
) { ) {
private val workingDir = File(args.first()) private val workingDir = File(args.first())
val currentKotlinVersion: String = args[1]
private val gradleProfilerDir = workingDir.resolve("gradle-profiler") private val gradleProfilerDir = workingDir.resolve("gradle-profiler")
private val projectRepoDir = workingDir.resolve(projectName) private val projectRepoDir = workingDir.resolve(projectName)
private val scenariosDir = workingDir.resolve("scenarios") private val scenariosDir = workingDir.resolve("scenarios")
@@ -44,9 +46,9 @@ abstract class BenchmarkTemplate(
private val gitOperationsPrinter = TextProgressMonitor() private val gitOperationsPrinter = TextProgressMonitor()
fun runAllBenchmarks( fun <T : InputStream> runAllBenchmarks(
suite: ScenarioSuite, suite: ScenarioSuite,
benchmarks: Map<BenchmarkName, PatchFile?> benchmarks: Map<BenchmarkName, (() -> Pair<String, T>)?>
) { ) {
printStartingMessage() printStartingMessage()
downloadGradleProfilerIfNotAvailable() downloadGradleProfilerIfNotAvailable()
@@ -54,7 +56,10 @@ abstract class BenchmarkTemplate(
val results = benchmarks.map { (name, patchFile) -> val results = benchmarks.map { (name, patchFile) ->
repoReset() repoReset()
patchFile?.let { repoApplyPatch(it) } patchFile?.let {
val (patchName, patch) = it()
repoApplyPatch(patchName, patch)
}
runBenchmark(suite, name) runBenchmark(suite, name)
} }
aggregateBenchmarkResults(*results.toTypedArray()) aggregateBenchmarkResults(*results.toTypedArray())
@@ -106,12 +111,21 @@ abstract class BenchmarkTemplate(
return projectRepoDir return projectRepoDir
} }
fun repoApplyPatch(patchFile: PatchFile) { fun repoApplyPatchFromFile(
println("Applying patch $patchFile to repository") patchFile: String
) {
val patch = File(patchFile) val patch = File(patchFile)
repoApplyPatch(patch.name, patch.inputStream())
}
fun repoApplyPatch(
patchName: String,
patch: InputStream
) {
println("Applying patch $patchName to repository")
Git.open(projectRepoDir) Git.open(projectRepoDir)
.apply() .apply()
.setPatch(patch.inputStream()) .setPatch(patch)
.call() .call()
} }
@@ -359,7 +373,6 @@ abstract class BenchmarkTemplate(
} }
typealias BenchmarkName = String typealias BenchmarkName = String
typealias PatchFile = String
class BenchmarkFailedException(exitCode: Int) : Exception( class BenchmarkFailedException(exitCode: Int) : Exception(
"Benchmark process was not finished successfully with $exitCode exit code." "Benchmark process was not finished successfully with $exitCode exit code."
@@ -2,7 +2,8 @@
Contains build regression benchmark scripts for different user projects. Contains build regression benchmark scripts for different user projects.
Such benchmarks comparing different build scenarios between last stable Kotlin release and current-in-progress release helping to identify build speed regressions. Such benchmarks comparing different build scenarios between last stable Kotlin release and current-in-progress release helping
to identify build speed regressions with minimal user-project modifications.
All scripts should run via related Gradle task which could be found in "Gradle Regression Benchmark tasks" task group. All scripts should run via related Gradle task which could be found in "Gradle Regression Benchmark tasks" task group.
@@ -15,5 +16,6 @@ All scripts are using infrastructure provided by [template](../regression-benchm
- Add required `@file:BenchmarkProject` annotation and few steps that will download profiler plus project itself - Add required `@file:BenchmarkProject` annotation and few steps that will download profiler plus project itself
- Inspect user-project and create required git patches to change Kotlin version in the project - add changes, test it - Inspect user-project and create required git patches to change Kotlin version in the project - add changes, test it
and use `git diff --no-color > name.patch` command. Put created patches into `benchmarkScripts/files` directory. and use `git diff --no-color > name.patch` command. Put created patches into `benchmarkScripts/files` directory.
- Update current Kotlin version patch to use Kotlin version passed as argument to script and available as `currentKotlinVersion`
- Write benchmark scenarios and run benchmark with `dryRun = true` flag - Write benchmark scenarios and run benchmark with `dryRun = true` flag
- Add final changes to script, probably convert it to use `runAllBenchmarks()` function - Add final changes to script, probably convert it to use `runAllBenchmarks()` function
@@ -1,13 +1,25 @@
// Android application written in Kotlin: // Android application written in Kotlin:
// - kind of big codebase // - kind of big codebase
// - uses Kotlin compiler plugins and kapt // - uses Kotlin compiler plugins and kapt
@file:BenchmarkProject( @file:BenchmarkProject(
name = "duckduckgo", name = "duckduckgo",
gitUrl = "https://github.com/duckduckgo/Android.git", gitUrl = "https://github.com/duckduckgo/Android.git",
gitCommitSha = "659bd5aaac1fba922a6df9053daa2b7bcd610375" gitCommitSha = "659bd5aaac1fba922a6df9053daa2b7bcd610375"
) )
import java.io.File
val stableReleasePatch = {
"duckduckgo-kotlin-1.6.10.patch" to File("benchmarkScripts/files/duckduckgo-kotlin-1.6.10.patch").inputStream()
}
val currentReleasePatch = {
"duckduckgo-kotlin-current.patch" to File("benchmarkScripts/files/duckduckgo-kotlin-current.patch")
.readText()
.run { replace("<kotlin_version>", currentKotlinVersion) }
.byteInputStream()
}
runAllBenchmarks( runAllBenchmarks(
suite { suite {
scenario { scenario {
@@ -31,7 +43,7 @@ runAllBenchmarks(
} }
}, },
mapOf( mapOf(
"1.6.10" to "benchmarkScripts/files/duckduckgo-kotlin-1.6.10.patch", "1.6.10" to stableReleasePatch,
"1.6.20" to "benchmarkScripts/files/duckduckgo-kotlin-current.patch" "1.6.20" to currentReleasePatch
) )
) )
@@ -27,7 +27,7 @@ index 4497fd12..730df20a 100644
ext { ext {
- kotlin_version = '1.5.10' - kotlin_version = '1.5.10'
+ kotlin_version = '1.6.255-SNAPSHOT' + kotlin_version = '<kotlin_version>'
} }
ext.spotless = "5.14.0" ext.spotless = "5.14.0"
- ext.anvil_version = "2.3.3" - ext.anvil_version = "2.3.3"
@@ -67,7 +67,7 @@ index fae6ae6e..81cb692c 100644
version.io.reactivex.rxjava2..rxjava=2.2.9 version.io.reactivex.rxjava2..rxjava=2.2.9
-version.kotlin=1.5.31 -version.kotlin=1.5.31
+version.kotlin=1.6.255-SNAPSHOT +version.kotlin=<kotlin_version>
version.kotlinx.coroutines=1.5.2 version.kotlinx.coroutines=1.5.2
@@ -23,7 +23,8 @@ dependencies {
val service = project.extensions.getByType<JavaToolchainService>() val service = project.extensions.getByType<JavaToolchainService>()
abstract class ScriptArgumentProvider @Inject constructor( abstract class ScriptArgumentProvider @Inject constructor(
layout: ProjectLayout layout: ProjectLayout,
private val releaseKotlinVersion: String
) : CommandLineArgumentProvider { ) : CommandLineArgumentProvider {
@get:Classpath @get:Classpath
abstract val scriptClasspath: ConfigurableFileCollection abstract val scriptClasspath: ConfigurableFileCollection
@@ -40,7 +41,8 @@ abstract class ScriptArgumentProvider @Inject constructor(
"-no-stdlib", "-no-stdlib",
"-classpath", scriptClasspath.asFileTree.files.joinToString(separator = File.pathSeparator), "-classpath", scriptClasspath.asFileTree.files.joinToString(separator = File.pathSeparator),
"-script", "benchmarkScripts/${script.get()}", "-script", "benchmarkScripts/${script.get()}",
scriptOutputDirectories.get().asFile.absolutePath scriptOutputDirectories.get().asFile.absolutePath,
releaseKotlinVersion
) )
} }
} }
@@ -62,7 +64,7 @@ fun addBenchmarkTask(
classpath = compilerClasspath classpath = compilerClasspath
mainClass.set("org.jetbrains.kotlin.cli.jvm.K2JVMCompiler") mainClass.set("org.jetbrains.kotlin.cli.jvm.K2JVMCompiler")
val scriptArgs = objects.newInstance<ScriptArgumentProvider>() val scriptArgs = objects.newInstance<ScriptArgumentProvider>(version)
scriptArgs.script.set(script) scriptArgs.script.set(script)
scriptArgs.scriptClasspath.from(scriptsClasspath) scriptArgs.scriptClasspath.from(scriptsClasspath)
argumentProviders.add(scriptArgs) argumentProviders.add(scriptArgs)