typetools / typetools/checker-framework

Possible performance improvement on AnnotationUtils.areSameByClass() invocations

Open
#2,958 3 comments 0 reactions 1 assignee View on GitHub

@smillst is already working on this.

Since Dec 16, 2019.

Dominant language
Java
Stars
1.1k
Forks
440
Avg merge
1d 12h
Merged PRs (30d)
134

Description

The "client code" that uses AnnotationUtils.areSameByClass(annotation, *.class) follows a pattern. Some 353 places where it is used to "compare the annotation to the interface class"
Example:

Line 208:                 if (AnnotationUtils.areSameByClass(a1, SameLenUnknown.class)) {
Line 210:                 } else if (AnnotationUtils.areSameByClass(a2, SameLenUnknown.class)) {
Line 236:                 if (AnnotationUtils.areSameByClass(a1, SameLenBottom.class)) {
Line 238:                 } else if (AnnotationUtils.areSameByClass(a2, SameLenBottom.class)) {
Line 240:                 } else if (AnnotationUtils.areSameByClass(a1, PolySameLen.class)
Line 241:                         && AnnotationUtils.areSameByClass(a2, PolySameLen.class)) {
Line 251:             if (AnnotationUtils.areSameByClass(subAnno, SameLenBottom.class)) {
Line 253:             } else if (AnnotationUtils.areSameByClass(superAnno, SameLenUnknown.class)) {
Line 255:             } else if (AnnotationUtils.areSameByClass(subAnno, PolySameLen.class)) {
Line 256:                 return AnnotationUtils.areSameByClass(superAnno, PolySameLen.class);
Line 299:                         if (AnnotationUtils.areSameByClass(sequenceAnno, SameLenUnknown.class)) {
Line 301:                         } else if (AnnotationUtils.areSameByClass(sequenceAnno, SameLen.class)) {
Line 391:             if (AnnotationUtils.areSameByClass(anno, SameLen.class)) 
public static boolean areSameByClass(AnnotationMirror am, Class<? extends Annotation> annoClass) {

The second argument to the method (annoClass) being a ".class" is a singleton and immutable.

The current implementation of areSameByClass does not take advantage of that fact; it uses a collection to cache its name and goes in that direction.

I am suggesting that we evaluate once each of those second argument classes into static final CheckerFrameworkAnnotationMirror instances and then use a boolean matches(anno) method that tells if the annotation "belongs to/matches" the class.

Example:

if (AnnotationUtils.areSameByClass(a1, SameLenUnknown.class)) {

turns into

if ( Annotations.SameLenUnknown.matches(a1)) {

where

Annotations.java
{
public static final CheckerFrameworkAnnotationMirror SameLenUnknown= new CheckerFrameworkAnnotationMirror(SameLenUnknown.class);

Meaning that all evaluations of canonical names for all of those annoClass happens once, there is no need to involve a cache collection, and the comparison of the constant vs the annotation that we want to identify is encapsulated in the class CheckerFrameworkAnnotationMirror() that takes a Class<? extends Annotation> annoClass.

The bulk of the source code transformation can be done by refactoring tools so nothing is missed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.