Add highlighting perf test with empty profile

This commit is contained in:
Vladimir Dolzhenko
2020-05-02 23:12:36 +02:00
parent 32be4c03ca
commit 911dfde0fe
4 changed files with 80 additions and 55 deletions
@@ -11,6 +11,7 @@ import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl
import com.intellij.codeInsight.daemon.impl.HighlightInfo import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.IdentifierHighlighterPassFactory import com.intellij.codeInsight.daemon.impl.IdentifierHighlighterPassFactory
import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInspection.InspectionProfileEntry
import com.intellij.ide.startup.impl.StartupManagerImpl import com.intellij.ide.startup.impl.StartupManagerImpl
import com.intellij.openapi.actionSystem.IdeActions import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.openapi.application.runWriteAction import com.intellij.openapi.application.runWriteAction
@@ -23,13 +24,11 @@ import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl
import com.intellij.openapi.startup.StartupManager import com.intellij.openapi.startup.StartupManager
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager import com.intellij.psi.PsiManager
import com.intellij.testFramework.EditorTestUtil import com.intellij.testFramework.*
import com.intellij.testFramework.RunAll
import com.intellij.testFramework.TestDataProvider
import com.intellij.testFramework.UsefulTestCase
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl
import com.intellij.util.ArrayUtilRt import com.intellij.util.ArrayUtilRt
import com.intellij.util.ThrowableRunnable import com.intellij.util.ThrowableRunnable
@@ -92,7 +91,7 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
val project = openProject() val project = openProject()
try { try {
filesToHighlight.forEach { filesToHighlight.forEach {
val perfHighlightFile = perfHighlightFile(project, it, stats, WARM_UP) val perfHighlightFile = perfHighlightFile(project, it, stats, note = WARM_UP)
assertTrue("kotlin project has been not imported properly", perfHighlightFile.isNotEmpty()) assertTrue("kotlin project has been not imported properly", perfHighlightFile.isNotEmpty())
} }
} finally { } finally {
@@ -319,14 +318,14 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
val editor = fixture.editor val editor = fixture.editor
val initialText = editor.document.text val initialText = editor.document.text
updateScriptDependenciesIfNeeded(fileName, fixture, project) updateScriptDependenciesIfNeeded(fileName, fixture)
performanceTest<Unit, V> { performanceTest<Unit, V> {
name("$typeTestPrefix ${notePrefix(note)}$fileName") name("$typeTestPrefix ${notePrefix(note)}$fileName")
stats(stats) stats(stats)
warmUpIterations(8) warmUpIterations(8)
iterations(15) iterations(15)
profileEnabled(true) profilerEnabled(true)
setUp { setUp {
val markerOffset = editor.document.text.indexOf(marker) val markerOffset = editor.document.text.indexOf(marker)
assertTrue("marker '$marker' not found in $fileName", markerOffset > 0) assertTrue("marker '$marker' not found in $fileName", markerOffset > 0)
@@ -404,7 +403,7 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
val editor = fixture.editor val editor = fixture.editor
val initialText = editor.document.text val initialText = editor.document.text
updateScriptDependenciesIfNeeded(fileName, fixture, project) updateScriptDependenciesIfNeeded(fileName, fixture)
val tasksIdx = editor.document.text.indexOf(marker) val tasksIdx = editor.document.text.indexOf(marker)
assertTrue("marker '$marker' not found in $fileName", tasksIdx > 0) assertTrue("marker '$marker' not found in $fileName", tasksIdx > 0)
@@ -444,7 +443,7 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
} }
commitAllDocuments() commitAllDocuments()
} }
profileEnabled(true) profilerEnabled(true)
} }
} }
@@ -488,7 +487,7 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
val editor = fixture.editor val editor = fixture.editor
val initialText = editor.document.text val initialText = editor.document.text
updateScriptDependenciesIfNeeded(fileName, fixture, project) updateScriptDependenciesIfNeeded(fileName, fixture)
val tasksIdx = editor.document.text.indexOf(marker) val tasksIdx = editor.document.text.indexOf(marker)
assertTrue("marker '$marker' not found in $fileName", tasksIdx > 0) assertTrue("marker '$marker' not found in $fileName", tasksIdx > 0)
@@ -530,7 +529,7 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
} }
commitAllDocuments() commitAllDocuments()
} }
profileEnabled(true) profilerEnabled(true)
} }
} }
@@ -572,8 +571,8 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
val initialText2 = fixture2.document.text val initialText2 = fixture2.document.text
updateScriptDependenciesIfNeeded(sourceFileName, fixture1, project) updateScriptDependenciesIfNeeded(sourceFileName, fixture1)
updateScriptDependenciesIfNeeded(sourceFileName, fixture2, project) updateScriptDependenciesIfNeeded(sourceFileName, fixture2)
fixture1.selectMarkers(sourceInitialMarker, sourceFinalMarker) fixture1.selectMarkers(sourceInitialMarker, sourceFinalMarker)
fixture2.selectMarkers(targetInitialMarker, targetFinalMarker) fixture2.selectMarkers(targetInitialMarker, targetFinalMarker)
@@ -605,14 +604,13 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
commitAllDocuments() commitAllDocuments()
} }
} }
profileEnabled(true) profilerEnabled(true)
} }
} }
private fun updateScriptDependenciesIfNeeded( private fun updateScriptDependenciesIfNeeded(
fileName: String, fileName: String,
fixture: Fixture, fixture: Fixture
project: Project
) { ) {
if (isAKotlinScriptFile(fileName)) { if (isAKotlinScriptFile(fileName)) {
runAndMeasure("update script dependencies for $fileName") { runAndMeasure("update script dependencies for $fileName") {
@@ -621,39 +619,56 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
} }
} }
protected fun perfHighlightFile(name: String, stats: Stats): List<HighlightInfo> =
perfHighlightFile(project(), name, stats)
protected fun perfHighlightFile( protected fun perfHighlightFile(
name: String,
stats: Stats,
tools: Array<InspectionProfileEntry>? = null,
note: String = ""
): List<HighlightInfo> = perfHighlightFile(project(), name, stats, tools = tools, note = note)
protected fun perfHighlightFileEmptyProfile(name: String, stats: Stats): List<HighlightInfo> =
perfHighlightFile(project(), name, stats, tools = emptyArray(), note = "empty profile")
private fun perfHighlightFile(
project: Project, project: Project,
fileName: String, fileName: String,
stats: Stats, stats: Stats,
tools: Array<InspectionProfileEntry>? = null,
note: String = "" note: String = ""
): List<HighlightInfo> { ): List<HighlightInfo> {
return highlightFile { val profileManager = ProjectInspectionProfileManager.getInstance(project)
val isWarmUp = note == WARM_UP val currentProfile = profileManager.currentProfile
var highlightInfos: List<HighlightInfo> = emptyList() tools?.let {
performanceTest<EditorFile, List<HighlightInfo>> { configureInspections(it, project, project)
name("highlighting ${notePrefix(note)}${simpleFilename(fileName)}") }
stats(stats) try {
warmUpIterations(if (isWarmUp) 1 else 3) return highlightFile {
iterations(if (isWarmUp) 2 else 10) val isWarmUp = note == WARM_UP
setUp { var highlightInfos: List<HighlightInfo> = emptyList()
it.setUpValue = openFileInEditor(project, fileName) performanceTest<EditorFile, List<HighlightInfo>> {
name("highlighting ${notePrefix(note)}${simpleFilename(fileName)}")
stats(stats)
warmUpIterations(if (isWarmUp) 1 else 3)
iterations(if (isWarmUp) 2 else 10)
setUp {
it.setUpValue = openFileInEditor(project, fileName)
}
test {
val file = it.setUpValue
it.value = highlightFile(project, file!!.psiFile)
}
tearDown {
highlightInfos = it.value ?: emptyList()
commitAllDocuments()
FileEditorManager.getInstance(project).closeFile(it.setUpValue!!.psiFile.virtualFile)
PsiManager.getInstance(project).dropPsiCaches()
}
profilerEnabled(!isWarmUp)
} }
test { highlightInfos
val file = it.setUpValue
it.value = highlightFile(project, file!!.psiFile)
}
tearDown {
highlightInfos = it.value ?: emptyList()
commitAllDocuments()
FileEditorManager.getInstance(project).closeFile(it.setUpValue!!.psiFile.virtualFile)
PsiManager.getInstance(project).dropPsiCaches()
}
profileEnabled(!isWarmUp)
} }
highlightInfos } finally {
profileManager.setCurrentProfile(currentProfile)
} }
} }
@@ -701,7 +716,7 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
} }
it.value?.let { v -> assertNotNull(v) } it.value?.let { v -> assertNotNull(v) }
} }
profileEnabled(true) profilerEnabled(true)
checkStability(false) checkStability(false)
} }
} }
@@ -13,7 +13,7 @@ class PerfTestBuilder<SV, TV> {
private var setUp: (TestData<SV, TV>) -> Unit = { } private var setUp: (TestData<SV, TV>) -> Unit = { }
private lateinit var test: (TestData<SV, TV>) -> Unit private lateinit var test: (TestData<SV, TV>) -> Unit
private var tearDown: (TestData<SV, TV>) -> Unit = { } private var tearDown: (TestData<SV, TV>) -> Unit = { }
private var profileEnabled: Boolean = false private var profilerEnabled: Boolean = false
private var checkStability: Boolean = true private var checkStability: Boolean = true
internal fun run() { internal fun run() {
@@ -24,7 +24,7 @@ class PerfTestBuilder<SV, TV> {
setUp = setUp, setUp = setUp,
test = test, test = test,
tearDown = tearDown, tearDown = tearDown,
profileEnabled = profileEnabled, profilerEnabled = profilerEnabled,
checkStability = checkStability checkStability = checkStability
) )
} }
@@ -57,8 +57,8 @@ class PerfTestBuilder<SV, TV> {
this.tearDown = tearDown this.tearDown = tearDown
} }
fun profileEnabled(profileEnabled: Boolean) { fun profilerEnabled(profilerEnabled: Boolean) {
this.profileEnabled = profileEnabled this.profilerEnabled = profilerEnabled
} }
fun checkStability(checkStability: Boolean) { fun checkStability(checkStability: Boolean) {
@@ -77,11 +77,21 @@ class PerformanceProjectsTest : AbstractPerformanceProjectsTest() {
stats.use { stats.use {
perfOpenKotlinProject(it) perfOpenKotlinProject(it)
perfHighlightFile("idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/PsiPrecedences.kt", stats = it) val filesToHighlight = arrayOf(
"idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/PsiPrecedences.kt",
"compiler/psi/src/org/jetbrains/kotlin/psi/KtElement.kt",
"compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt",
"core/builtins/native/kotlin/Primitives.kt",
perfHighlightFile("compiler/psi/src/org/jetbrains/kotlin/psi/KtElement.kt", stats = it) "compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt",
"compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt",
perfHighlightFile("compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt", stats = it) "compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt",
"compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt"
)
filesToHighlight.forEach { file -> perfHighlightFile(file, stats = it) }
filesToHighlight.forEach { file -> perfHighlightFileEmptyProfile(file, stats = it) }
perfTypeAndHighlight( perfTypeAndHighlight(
it, it,
@@ -282,7 +292,7 @@ class PerformanceProjectsTest : AbstractPerformanceProjectsTest() {
setUp(perfKtsFileAnalysisSetUp(project, fileName)) setUp(perfKtsFileAnalysisSetUp(project, fileName))
test(perfKtsFileAnalysisTest()) test(perfKtsFileAnalysisTest())
tearDown(perfKtsFileAnalysisTearDown(extraTimingsNs, project)) tearDown(perfKtsFileAnalysisTearDown(extraTimingsNs, project))
profileEnabled(true) profilerEnabled(true)
} }
extraStats.printWarmUpTimings( extraStats.printWarmUpTimings(
@@ -125,7 +125,7 @@ class Stats(
setUp: (TestData<SV, TV>) -> Unit = { }, setUp: (TestData<SV, TV>) -> Unit = { },
test: (TestData<SV, TV>) -> Unit, test: (TestData<SV, TV>) -> Unit,
tearDown: (TestData<SV, TV>) -> Unit = { }, tearDown: (TestData<SV, TV>) -> Unit = { },
profileEnabled: Boolean = false, profilerEnabled: Boolean = false,
checkStability: Boolean = true checkStability: Boolean = true
) { ) {
@@ -135,7 +135,7 @@ class Stats(
setUp = setUp, setUp = setUp,
test = test, test = test,
tearDown = tearDown, tearDown = tearDown,
profileEnabled = profileEnabled profilerEnabled = profilerEnabled
) )
val mainPhaseData = PhaseData( val mainPhaseData = PhaseData(
iterations = iterations, iterations = iterations,
@@ -143,7 +143,7 @@ class Stats(
setUp = setUp, setUp = setUp,
test = test, test = test,
tearDown = tearDown, tearDown = tearDown,
profileEnabled = profileEnabled profilerEnabled = profilerEnabled
) )
val block = { val block = {
warmUpPhase(warmPhaseData) warmUpPhase(warmPhaseData)
@@ -307,7 +307,7 @@ class Stats(
phaseName: String, phaseName: String,
attempt: Int attempt: Int
): PhaseProfiler { ): PhaseProfiler {
val profilerHandler = if (phaseData.profileEnabled) ProfilerHandler.getInstance() else DummyProfilerHandler val profilerHandler = if (phaseData.profilerEnabled) ProfilerHandler.getInstance() else DummyProfilerHandler
return if (profilerHandler != DummyProfilerHandler) { return if (profilerHandler != DummyProfilerHandler) {
val profilerPath = pathToResource("profile/${plainname()}") val profilerPath = pathToResource("profile/${plainname()}")
@@ -429,7 +429,7 @@ data class PhaseData<SV, TV>(
val setUp: (TestData<SV, TV>) -> Unit, val setUp: (TestData<SV, TV>) -> Unit,
val test: (TestData<SV, TV>) -> Unit, val test: (TestData<SV, TV>) -> Unit,
val tearDown: (TestData<SV, TV>) -> Unit, val tearDown: (TestData<SV, TV>) -> Unit,
val profileEnabled: Boolean = false val profilerEnabled: Boolean = false
) )
data class TestData<SV, TV>(var setUpValue: SV?, var value: TV?) { data class TestData<SV, TV>(var setUpValue: SV?, var value: TV?) {