Speed up REPL package member declaration provider

about 10-15% on specific test
also preparing test infrastructure for it
This commit is contained in:
Ilya Chernikov
2020-01-17 11:56:00 +01:00
parent cb7cc8ac6b
commit c7d9eaed40
2 changed files with 42 additions and 9 deletions
@@ -113,12 +113,36 @@ class ReplTest : TestCase() {
) )
) )
} }
@Test
fun testLongEval() {
checkEvaluateInRepl(
sequence {
var count = 0
while (true) {
val prev = if (count == 0) "0" else "obj${count - 1}.prop${count - 1} + $count"
yield("object obj$count { val prop$count = $prev }; $prev")
count++
}
},
sequence {
var acc = 0
var count = 0
while (true) {
yield(acc)
acc += ++count
}
},
limit = 100
)
}
} }
fun evaluateInRepl( fun evaluateInRepl(
snippets: Sequence<String>, snippets: Sequence<String>,
compilationConfiguration: ScriptCompilationConfiguration = simpleScriptompilationConfiguration, compilationConfiguration: ScriptCompilationConfiguration = simpleScriptompilationConfiguration,
evaluationConfiguration: ScriptEvaluationConfiguration? = simpleScriptEvaluationConfiguration evaluationConfiguration: ScriptEvaluationConfiguration? = simpleScriptEvaluationConfiguration,
limit: Int = 0
): Sequence<ResultWithDiagnostics<EvaluationResult>> { ): Sequence<ResultWithDiagnostics<EvaluationResult>> {
val replCompilerProxy = val replCompilerProxy =
KJvmReplCompilerImpl(defaultJvmScriptingHostConfiguration) KJvmReplCompilerImpl(defaultJvmScriptingHostConfiguration)
@@ -126,7 +150,8 @@ fun evaluateInRepl(
val compilationHistory = BasicReplStageHistory<ScriptDescriptor>() val compilationHistory = BasicReplStageHistory<ScriptDescriptor>()
val replEvaluator = BasicJvmScriptEvaluator() val replEvaluator = BasicJvmScriptEvaluator()
var currentEvalConfig = evaluationConfiguration ?: ScriptEvaluationConfiguration() var currentEvalConfig = evaluationConfiguration ?: ScriptEvaluationConfiguration()
return snippets.mapIndexed { snippetNo, snippetText -> val snipetsLimited = if (limit == 0) snippets else snippets.take(limit)
return snipetsLimited.mapIndexed { snippetNo, snippetText ->
val snippetSource = snippetText.toScriptSource("Line_$snippetNo.${compilationConfiguration[ScriptCompilationConfiguration.fileExtension]}") val snippetSource = snippetText.toScriptSource("Line_$snippetNo.${compilationConfiguration[ScriptCompilationConfiguration.fileExtension]}")
val snippetId = ReplSnippetIdImpl(snippetNo, 0, snippetSource) val snippetId = ReplSnippetIdImpl(snippetNo, 0, snippetSource)
replCompilerProxy.compileReplSnippet(compilationState, snippetSource, snippetId, compilationHistory) replCompilerProxy.compileReplSnippet(compilationState, snippetSource, snippetId, compilationHistory)
@@ -154,10 +179,11 @@ fun checkEvaluateInReplDiags(
snippets: Sequence<String>, snippets: Sequence<String>,
expected: Sequence<ResultWithDiagnostics<Any?>>, expected: Sequence<ResultWithDiagnostics<Any?>>,
compilationConfiguration: ScriptCompilationConfiguration = simpleScriptompilationConfiguration, compilationConfiguration: ScriptCompilationConfiguration = simpleScriptompilationConfiguration,
evaluationConfiguration: ScriptEvaluationConfiguration? = simpleScriptEvaluationConfiguration evaluationConfiguration: ScriptEvaluationConfiguration? = simpleScriptEvaluationConfiguration,
limit: Int = 0
) { ) {
val expectedIter = expected.iterator() val expectedIter = (if (limit == 0) expected else expected.take(limit)).iterator()
evaluateInRepl(snippets, compilationConfiguration, evaluationConfiguration).forEachIndexed { index, res -> evaluateInRepl(snippets, compilationConfiguration, evaluationConfiguration, limit).forEachIndexed { index, res ->
val expectedRes = expectedIter.next() val expectedRes = expectedIter.next()
when { when {
res is ResultWithDiagnostics.Failure && expectedRes is ResultWithDiagnostics.Failure -> { res is ResultWithDiagnostics.Failure && expectedRes is ResultWithDiagnostics.Failure -> {
@@ -187,16 +213,19 @@ fun checkEvaluateInReplDiags(
} }
} }
} }
if (expectedIter.hasNext()) {
Assert.fail("Expected ${expectedIter.next()} got end of results stream")
}
} }
fun checkEvaluateInRepl( fun checkEvaluateInRepl(
snippets: Sequence<String>, snippets: Sequence<String>,
expected: Sequence<Any?>, expected: Sequence<Any?>,
compilationConfiguration: ScriptCompilationConfiguration = simpleScriptompilationConfiguration, compilationConfiguration: ScriptCompilationConfiguration = simpleScriptompilationConfiguration,
evaluationConfiguration: ScriptEvaluationConfiguration? = simpleScriptEvaluationConfiguration evaluationConfiguration: ScriptEvaluationConfiguration? = simpleScriptEvaluationConfiguration,
limit: Int = 0
) = checkEvaluateInReplDiags( ) = checkEvaluateInReplDiags(
snippets, expected.map { ResultWithDiagnostics.Success(it) }, compilationConfiguration, snippets, expected.map { ResultWithDiagnostics.Success(it) }, compilationConfiguration, evaluationConfiguration, limit
evaluationConfiguration
) )
class TestReceiver(val prop1: Int = 3) class TestReceiver(val prop1: Int = 3)
@@ -164,7 +164,11 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
private var delegateProvider: PackageMemberDeclarationProvider private var delegateProvider: PackageMemberDeclarationProvider
) : DelegatePackageMemberDeclarationProvider(delegateProvider) { ) : DelegatePackageMemberDeclarationProvider(delegateProvider) {
fun addDelegateProvider(provider: PackageMemberDeclarationProvider) { fun addDelegateProvider(provider: PackageMemberDeclarationProvider) {
delegateProvider = CombinedPackageMemberDeclarationProvider(listOf(provider, delegateProvider)) val combinedDelegateProvider = delegateProvider as? CombinedPackageMemberDeclarationProvider
val providers =
if (combinedDelegateProvider != null) listOf(provider) + combinedDelegateProvider.providers
else listOf(provider, delegateProvider)
delegateProvider = CombinedPackageMemberDeclarationProvider(providers)
delegate = delegateProvider delegate = delegateProvider
} }