Create benchmark for light tree FIR builder (including coroutines test)

This commit is contained in:
Ivan Cilcic
2019-06-03 13:41:07 +03:00
committed by Mikhail Glukhikh
parent 0a8d0baa59
commit f07d85eb83
13 changed files with 153 additions and 62 deletions
+1
View File
@@ -0,0 +1 @@
testData
+20 -1
View File
@@ -1,10 +1,16 @@
import org.ajoberstar.grgit.Grgit
plugins {
kotlin("jvm")
id("org.jetbrains.intellij") version "0.4.5"
//git plugin
id("org.ajoberstar.grgit") version "3.1.1"
}
group = "org.jetbrains.kotlin.fir"
val jmhVersion = "1.21"
val testDataPath = "$rootDir/compiler/fir/lightTree/testData/coroutines"
repositories {
mavenCentral()
@@ -92,4 +98,17 @@ val jmhExec by tasks.creating(JavaExec::class) {
systemProperty("idea.home.path", project.intellij.localPath)
systemProperty("idea.max.intellisense.filesize", 5000 * 1024)
configurations.plusAssign(project.configurations["compile"])
}
}
val deleteGitFolder by tasks.creating(Delete::class) {
delete("$testDataPath/.git")
}
val cloneCoroutines by tasks.creating {
val url = "https://github.com/Kotlin/kotlinx.coroutines.git"
if (!File(testDataPath).exists()) {
Grgit.clone(mapOf("dir" to testDataPath,
"uri" to url)).close()
}
finalizedBy(tasks["deleteGitFolder"])
}
@@ -18,7 +18,11 @@ import org.jetbrains.kotlin.parsing.MyKotlinParser
import java.io.File
import java.nio.file.Path
class LightTree2Fir(private val stubMode: Boolean, private val parserDefinition: ParserDefinition, private val lexer: Lexer) {
class LightTree2Fir(
private val stubMode: Boolean,
private val parserDefinition: ParserDefinition,
private val lexer: Lexer
) {
fun buildFirFile(path: Path): FirFile {
return buildFirFile(path.toFile())
}
@@ -37,6 +41,7 @@ class LightTree2Fir(private val stubMode: Boolean, private val parserDefinition:
fun buildFirFile(code: String, fileName: String): FirFile {
val lightTree = buildLightTree(code)
return Converter(object : FirSessionBase() {}, stubMode, lightTree).convertFile(lightTree.root, fileName)
return Converter(object : FirSessionBase() {}, stubMode, lightTree)
.convertFile(lightTree.root, fileName)
}
}
@@ -18,6 +18,8 @@ import java.nio.file.Paths
@TestDataPath("\$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners::class)
class LightTree2FirConverterTestCases : AbstractRawFirBuilderTestCase() {
private val testDirPath = "compiler/fir/psi2fir/testData/rawBuilder/declarations"
private fun executeTest(filePath: String) {
val parserDefinition = KotlinParserDefinition()
val lexer = parserDefinition.createLexer(myProject)
@@ -31,78 +33,78 @@ class LightTree2FirConverterTestCases : AbstractRawFirBuilderTestCase() {
}
fun testComplexTypes() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/complexTypes.kt")
executeTest("$testDirPath/complexTypes.kt")
}
fun testDerivedClass() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt")
executeTest("$testDirPath/derivedClass.kt")
}
fun testEnums() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/enums.kt")
executeTest("$testDirPath/enums.kt")
}
fun testEnums2() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/enums2.kt")
executeTest("$testDirPath/enums2.kt")
}
fun testExpectActual() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/expectActual.kt")
executeTest("$testDirPath/expectActual.kt")
}
fun testF() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/F.kt")
executeTest("$testDirPath/F.kt")
}
fun testFunctionTypes() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/functionTypes.kt")
executeTest("$testDirPath/functionTypes.kt")
}
fun testGenericFunctions() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/genericFunctions.kt")
executeTest("$testDirPath/genericFunctions.kt")
}
fun testNestedClass() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/nestedClass.kt")
executeTest("$testDirPath/nestedClass.kt")
}
fun testNestedOfAliasedType() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/NestedOfAliasedType.kt")
executeTest("$testDirPath/NestedOfAliasedType.kt")
}
fun testNestedSuperType() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/NestedSuperType.kt")
executeTest("$testDirPath/NestedSuperType.kt")
}
fun testNoPrimaryConstructor() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/noPrimaryConstructor.kt")
executeTest("$testDirPath/noPrimaryConstructor.kt")
}
fun testSimpleClass() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/simpleClass.kt")
executeTest("$testDirPath/simpleClass.kt")
}
fun testSimpleFun() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/simpleFun.kt")
executeTest("$testDirPath/simpleFun.kt")
}
fun testSimpleTypeAlias() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/simpleTypeAlias.kt")
executeTest("$testDirPath/simpleTypeAlias.kt")
}
fun testTypeAliasWithGeneric() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/typeAliasWithGeneric.kt")
executeTest("$testDirPath/typeAliasWithGeneric.kt")
}
fun testTypeParameterVsNested() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameterVsNested.kt")
executeTest("$testDirPath/typeParameterVsNested.kt")
}
fun testTypeParameters() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.kt")
executeTest("$testDirPath/typeParameters.kt")
}
fun testWhere() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/where.kt")
executeTest("$testDirPath/where.kt")
}
}
@@ -7,16 +7,20 @@ package org.jetbrains.kotlin.fir.lightTree.benchmark
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.CharsetToolkit
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.TreeGenerator
import org.openjdk.jmh.annotations.*
import java.io.File
import java.util.concurrent.TimeUnit
@BenchmarkMode(Mode.SingleShotTime)
@Warmup(iterations = 5, batchSize = 1)
@Measurement(iterations = 5, batchSize = 1)
@Warmup(iterations = 10, batchSize = 1)
@Measurement(iterations = 10, batchSize = 1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(1)
open class AbstractBenchmark {
@State(Scope.Benchmark)
abstract class AbstractBenchmark {
private val files = mutableMapOf<String, Pair<File, String>>()
abstract val generator: TreeGenerator
protected fun readFiles(ignoreTestData: Boolean, path: String) {
val root = File(path)
@@ -42,4 +46,8 @@ open class AbstractBenchmark {
f(text, file)
}
}
protected fun getFilesCount(): Int {
return files.size
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.lightTree.benchmark
import org.openjdk.jmh.annotations.*
abstract class AbstractBenchmarkForGivenPath(
private val path: String,
private val ignoreTestData: Boolean = true
) : AbstractBenchmark() {
@Setup
fun setUp() {
generator.setUp()
readFiles(ignoreTestData, path)
println("FILES COUNT: ${getFilesCount()}")
}
@TearDown
fun tearDown() {
generator.tearDown()
}
@Benchmark
fun testBuildOnlyBaseTreeForGivenPath() {
forEachFile { text, file -> generator.generateBaseTree(text, file) }
}
@Benchmark
fun testBuildFirForGivenPath() {
forEachFile { text, file -> generator.generateFir(text, file) }
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.lightTree.benchmark.coroutines
import org.jetbrains.kotlin.fir.lightTree.benchmark.AbstractBenchmarkForGivenPath
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.LightTree2FirGenerator
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.Psi2FirGenerator
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.TreeGenerator
abstract class AbstractCoroutinesBenchmark :
AbstractBenchmarkForGivenPath(System.getProperty("user.dir") + "/compiler/fir/lightTree/testData/coroutines", false)
open class LightTree2FirCoroutinesBenchmark(override val generator: TreeGenerator = LightTree2FirGenerator()) :
AbstractCoroutinesBenchmark()
open class Psi2FirCoroutinesBenchmark(override val generator: TreeGenerator = Psi2FirGenerator()) :
AbstractCoroutinesBenchmark()
@@ -6,16 +6,14 @@
package org.jetbrains.kotlin.fir.lightTree.benchmark.createdFiles
import org.jetbrains.kotlin.fir.lightTree.benchmark.*
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.LightTree2FirGenerator
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.Psi2FirGenerator
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.TreeGenerator
import org.openjdk.jmh.annotations.*
import java.io.File
import java.util.concurrent.TimeUnit
@Warmup(iterations = 10, batchSize = 1, timeUnit = TimeUnit.NANOSECONDS)
@Measurement(iterations = 10, batchSize = 1, timeUnit = TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
abstract class AbstractKotlinBenchmark : AbstractBenchmark() {
abstract val generator: TreeGenerator
@Param(
/* CLASSES */
"1Class", "10Classes", "100Classes", "1000Classes", "10_000Classes", "100_000Classes",
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.lightTree.benchmark.firModule
import org.jetbrains.kotlin.fir.lightTree.benchmark.*
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.LightTree2FirGenerator
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.Psi2FirGenerator
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.TreeGenerator
abstract class AbstractFirModuleBenchmark :
AbstractBenchmarkForGivenPath(
System.getProperty("user.dir") + "/compiler/fir",
true
)
open class LightTree2FirBenchmarkFirModule(override val generator: TreeGenerator = LightTree2FirGenerator()) :
AbstractFirModuleBenchmark()
open class Psi2FirBenchmarkFirModule(override val generator: TreeGenerator = Psi2FirGenerator()) :
AbstractFirModuleBenchmark()
@@ -3,7 +3,7 @@
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.lightTree.benchmark
package org.jetbrains.kotlin.fir.lightTree.benchmark.generators
import com.intellij.psi.impl.DebugUtil
import org.jetbrains.kotlin.fir.FirRenderer
@@ -16,15 +16,15 @@ import java.io.File
@State(Scope.Benchmark)
open class LightTree2FirGenerator : TreeGenerator, AbstractRawFirBuilderTestCase() {
private var lightTreeConverter: LightTree2Fir? = null
private lateinit var lightTreeConverter: LightTree2Fir
override fun generateBaseTree(text: String, file: File) {
val lightTree = lightTreeConverter!!.buildLightTree(text)
val lightTree = lightTreeConverter.buildLightTree(text)
DebugUtil.lightTreeToString(lightTree, false)
}
override fun generateFir(text: String, file: File) {
val firFile = lightTreeConverter!!.buildFirFile(text, file.name)
val firFile = lightTreeConverter.buildFirFile(text, file.name)
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
}
@@ -3,7 +3,7 @@
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.lightTree.benchmark
package org.jetbrains.kotlin.fir.lightTree.benchmark.generators
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.impl.DebugUtil
@@ -3,7 +3,7 @@
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.lightTree.benchmark
package org.jetbrains.kotlin.fir.lightTree.benchmark.generators
import java.io.File
@@ -6,33 +6,13 @@
package org.jetbrains.kotlin.fir.lightTree.benchmark.totalKotlin
import org.jetbrains.kotlin.fir.lightTree.benchmark.*
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.LightTree2FirGenerator
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.Psi2FirGenerator
import org.jetbrains.kotlin.fir.lightTree.benchmark.generators.TreeGenerator
import org.openjdk.jmh.annotations.*
@State(Scope.Benchmark)
abstract class AbstractTotalKotlinBenchmark : AbstractBenchmark() {
abstract val generator: TreeGenerator
@Setup
fun setUp() {
generator.setUp()
readFiles(true, System.getProperty("user.dir"))
}
@TearDown
fun tearDown() {
generator.tearDown()
}
@Benchmark
fun testTotalKotlinOnlyBaseTree() {
forEachFile { text, file -> generator.generateBaseTree(text, file) }
}
@Benchmark
fun testTotalKotlinFir() {
forEachFile { text, file -> generator.generateFir(text, file) }
}
}
abstract class AbstractTotalKotlinBenchmark :
AbstractBenchmarkForGivenPath(System.getProperty("user.dir"))
open class LightTree2FirTotalKotlinBenchmark(override val generator: TreeGenerator = LightTree2FirGenerator()) :
AbstractTotalKotlinBenchmark()