Skip to content

🟠 [Performance] Redundant exporter checks β€” every class goes through ALL exportersΒ #668

@tangcent

Description

@tangcent

Problem

After findControllerClasses() already identifies which classes are API classes (and which framework they belong to), scanClassesWithExporters passes every class through every enabled exporter. Each exporter then does its own recognition check internally:

  • SpringMvcClassExporter.export(): controllerRecognizer.isController(psiClass) β†’ rule evaluation + meta-annotation scan
  • JaxRsClassExporter.export(): recognizer.isResource(psiClass) β†’ rule evaluation
  • FeignClassExporter.export(): recognizer.isFeignClient(psiClass) β†’ rule evaluation
  • GrpcClassExporter.export(): recognizer.isGrpcService(psiClass) β†’ rule evaluation
  • ActuatorEndpointExporter.export(): recognizer.isApiClass(psiClass) β†’ annotation check

Most of these checks will return false (a Spring controller is not a Feign client, not a gRPC service, etc.), but each still incurs the cost of rule evaluation and PSI annotation scanning.

Impact

For 100 controllers with 5 exporters enabled, that's 500 recognition checks, each involving rule evaluation. Most will return false.

Estimated speedup: 1.5-2x for multi-framework projects

Fix

Pre-classify classes during findControllerClasses() and route each class only to its matching exporter(s). The CompositeApiClassRecognizer.matchingFrameworks() method already exists for this purpose:

data class ClassifiedController(
    val psiClass: PsiClass,
    val frameworks: List<String>
)

// Then in scanClassesWithExporters, only pass to matching exporters
for ((index, classified) in classifiedControllers.withIndex()) {
    val matchingExporters = exporters.filter { exporter ->
        classified.frameworks.contains(exporter.frameworkName)
    }
    for (exporter in matchingExporters) {
        // export...
    }
}

Alternatively, add a frameworkName property to ClassExporter interface and use it for routing.

Location

  • src/main/kotlin/com/itangcent/easyapi/dashboard/ApiScanner.kt:279-324
  • src/main/kotlin/com/itangcent/easyapi/exporter/core/CompositeApiClassRecognizer.kt:55-58 (matchingFrameworks already exists)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions