forked from fwcd/kotlin-language-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
OneFilePerformance.kt
131 lines (120 loc) · 5.54 KB
/
OneFilePerformance.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package org.javacs.kt
import com.intellij.openapi.Disposable
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.VirtualFileSystem
import com.intellij.psi.PsiManager
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.cli.jvm.compiler.CliBindingTrace
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.container.ComponentProvider
import org.jetbrains.kotlin.container.ValueDescriptor
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer
import org.jetbrains.kotlin.resolve.TopDownAnalysisMode
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory
import org.junit.Test
import org.openjdk.jmh.annotations.Benchmark
import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State
import org.openjdk.jmh.runner.Runner
import org.openjdk.jmh.runner.RunnerException
import org.openjdk.jmh.runner.options.Options
import org.openjdk.jmh.runner.options.OptionsBuilder
import java.lang.reflect.Type
import java.net.URL
class OneFilePerformance {
@State(Scope.Thread)
class ReusableParts {
internal var config = CompilerConfiguration()
init {
config.put(CommonConfigurationKeys.MODULE_NAME, JvmAbi.DEFAULT_MODULE_NAME)
}
internal var env = KotlinCoreEnvironment.createForProduction(object: Disposable {
override fun dispose() {
// Do nothing
}
}, config, EnvironmentConfigFiles.JVM_CONFIG_FILES)
internal var parser = KtPsiFactory(env.project)
internal var fileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
internal var bigFile = openFile("/kotlinCompilerPerformance/BigFile.kt")
internal fun openFile(resourcePath: String?): KtFile {
val locate = OneFilePerformance::class.java.getResource(resourcePath)
val file = fileSystem.findFileByPath(locate.path)
return PsiManager.getInstance(env.project).findFile(file!!) as KtFile
}
internal fun compile(compile: Collection<KtFile>, sourcePath: Collection<KtFile>): BindingTraceContext {
val trace = CliBindingTrace()
val container = CompilerFixtures.createContainer(
env.project,
sourcePath,
trace,
env.configuration,
env::createPackagePartProvider
)
val analyze = container.create(LazyTopDownAnalyzer::class.java)
analyze.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, compile, DataFlowInfoFactory.EMPTY)
return trace
}
}
@Benchmark
fun recompileBigFile(state: ReusableParts) {
val path = listOf(state.bigFile)
state.compile(path, path)
}
@Benchmark
fun recompileSmallFile(state: ReusableParts) {
val smallFile = state.openFile("/kotlinCompilerPerformance/ReferencesBigFile.kt")
val analyze = state.compile(listOf(smallFile), listOf(smallFile, state.bigFile))
// Check reference
val ref = PsiTreeUtil.getNonStrictParentOfType(smallFile.findElementAt(80), KtElement::class.java)
val call = ref.getParentResolvedCall(analyze.getBindingContext(), false)
if (!call!!.getCandidateDescriptor().getName().asString().equals("max"))
throw RuntimeException("Expected BigFile.max but found " + call)
}
@Benchmark
fun recompileBoth(state: ReusableParts) {
val bigFile = state.openFile("/kotlinCompilerPerformance/BigFile.kt")
val smallFile = state.openFile("/kotlinCompilerPerformance/ReferencesBigFile.kt")
val analyze = state.compile(listOf(smallFile, bigFile), listOf(smallFile, bigFile))
// Check reference
val ref = PsiTreeUtil.getNonStrictParentOfType(smallFile.findElementAt(80), KtElement::class.java)
val call = ref.getParentResolvedCall(analyze.getBindingContext(), false)
if (!call!!.getCandidateDescriptor().getName().asString().equals("max"))
throw RuntimeException("Expected BigFile.max but found " + call)
}
@Test
fun checkRecompileBoth() {
val state = ReusableParts()
recompileBoth(state)
}
@Test
fun checkRecompileOne() {
val state = ReusableParts()
state.compile(setOf(state.bigFile), setOf(state.bigFile))
recompileSmallFile(state)
}
companion object {
@Throws(RunnerException::class, InterruptedException::class)
@JvmStatic fun main(args: Array<String>) {
val opt = OptionsBuilder().include(OneFilePerformance::class.java.getSimpleName())
.forks(1)
.threads(1)
.warmupIterations(5)
.measurementIterations(5)
.build()
Runner(opt).run()
}
}
}