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:
+20
-7
@@ -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
|
||||||
|
|||||||
+15
-3
@@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-2
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user