eclipse.jdt.ls icon indicating copy to clipboard operation
eclipse.jdt.ls copied to clipboard

Improve the constructor completion performance when new an object

Open testforstephen opened this issue 3 years ago • 1 comments

Use Case

List list = new A|

Performance Analysis

Here is the cpu profiling result of completion handler. Please note that the JDT index search operation is running on a standalone thread, so its time cost is not included in this screenshot. image

We can see that most of time is spent on three parts.

  • CompletionEngine.acceptConstructors() image The time-consuming part is used to compute the relevance. See the code of CompletionEngine.proposeConstructor(...), where it resolves the TypeBindings of each proposed types and uses TypeBinding to check the compatibility between the proposed type and expected type.

  • Language Server creates method proposal label Usually when the CompletionProposal from CompletionEngine has computed the parameter names, then language server reuses that in the method label. If not, the language server will find the source of the propose types, and then resolve the parameter names from source code.

    The question here is, when does the upstream CompletionProposal not include the parameter names? It depends on the underlying constructorDecl index table. For some binary classes whose bytecode may not include the original parameter names, BinaryIndexer cannot generate the parameter names into the index.

    For example, below are the constructorDecl index keys for ArrayList constructors from different JDKs. You will see JDK 1.8 doesn't include parameter names, but JDK 11 does.

    • AdoptOpenJDK 1.8
    "ArrayList/0/!䀀/java.util/"
    "ArrayList/1/!䠀/java.util/(I)V//”
    "ArrayList/1/!䠀/java.util/(Ljava\util\Collection<+TE;>;)V//”
    
    • AdoptOpenJDK 11
    "ArrayList/0/!䀀/java.util/"
    "ArrayList/1/!䠀/java.util/(I)V/initialCapacity/”
    "ArrayList/1/!䠀/java.util/(Ljava\util\Collection<+TE;>;)V/c/”
    
  • Language Server computes type arguments image Completion will auto append a diamond for those classes with type arguments. Since type arguments is not included in the constructorDecl indexer, the language server needs to resolve Java element of each proposed type and use Java model to determine if the type arguments are required.

Optimizations

  • Explore new approach for relevance (e.g. IntelliCode)
  • Shorten the proposal size
    • only suggest compatible types
    • when typing new , auto complete a short list of constructors such as those from the expected type.
  • Apply typeFilters before relevance calculation
  • Reuse Type Binding at completion engine stage for type arguments calculation
  • Not show parameter names in the completion labels (e.g. use arg0, arg1... instead)

testforstephen avatar Feb 18 '22 13:02 testforstephen

Here are the breakdown work items to improve constructor completion performance.

  • [x] when typing new , auto complete a short list of constructors such as those from the expected type.
    • https://github.com/eclipse/eclipse.jdt.ls/pull/2010
  • [x] Apply typeFilters before relevance calculation
    • https://bugs.eclipse.org/bugs/show_bug.cgi?id=578817
  • [ ] Reuse Type Binding at completion engine stage for type arguments calculation
    • https://bugs.eclipse.org/bugs/show_bug.cgi?id=578969

testforstephen avatar Mar 02 '22 04:03 testforstephen