@@ -79,7 +79,11 @@ abstract class AbstractBase<S extends ParameterDescription> extends FilterableLi
7979 * {@inheritDoc}
8080 */
8181 public boolean hasExplicitMetaData () {
82- for (ParameterDescription parameterDescription : this ) {
82+ // cache the size and make sure to avoid iterators here
83+ // this pattern reduces the number of allocations and also the CPU usage
84+ int size = size ();
85+ for (int i = 0 ; i < size ; i ++) {
86+ ParameterDescription parameterDescription = get (i );
8387 if (!parameterDescription .isNamed () || !parameterDescription .hasModifiers ()) {
8488 return false ;
8589 }
@@ -91,9 +95,12 @@ public boolean hasExplicitMetaData() {
9195 * {@inheritDoc}
9296 */
9397 public ByteCodeElement .Token .TokenList <ParameterDescription .Token > asTokenList (ElementMatcher <? super TypeDescription > matcher ) {
94- List <ParameterDescription .Token > tokens = new ArrayList <ParameterDescription .Token >(size ());
95- for (ParameterDescription parameterDescription : this ) {
96- tokens .add (parameterDescription .asToken (matcher ));
98+ // cache the size and make sure to avoid iterators here
99+ // this pattern reduces the number of allocations and also the CPU usage
100+ int size = size ();
101+ List <ParameterDescription .Token > tokens = new ArrayList <ParameterDescription .Token >(size );
102+ for (int i = 0 ; i < size ; i ++) {
103+ tokens .add (get (i ).asToken (matcher ));
97104 }
98105 return new ByteCodeElement .Token .TokenList <ParameterDescription .Token >(tokens );
99106 }
@@ -102,9 +109,12 @@ public ByteCodeElement.Token.TokenList<ParameterDescription.Token> asTokenList(E
102109 * {@inheritDoc}
103110 */
104111 public TypeList .Generic asTypeList () {
105- List <TypeDescription .Generic > types = new ArrayList <TypeDescription .Generic >(size ());
106- for (ParameterDescription parameterDescription : this ) {
107- types .add (parameterDescription .getType ());
112+ // cache the size and make sure to avoid iterators here
113+ // this pattern reduces the number of allocations and also the CPU usage
114+ int size = size ();
115+ List <TypeDescription .Generic > types = new ArrayList <TypeDescription .Generic >(size );
116+ for (int i = 0 ; i < size ; i ++) {
117+ types .add (get (i ).getType ());
108118 }
109119 return new TypeList .Generic .Explicit (types );
110120 }
@@ -113,9 +123,12 @@ public TypeList.Generic asTypeList() {
113123 * {@inheritDoc}
114124 */
115125 public ParameterList <ParameterDescription .InDefinedShape > asDefined () {
116- List <ParameterDescription .InDefinedShape > declaredForms = new ArrayList <ParameterDescription .InDefinedShape >(size ());
117- for (ParameterDescription parameterDescription : this ) {
118- declaredForms .add (parameterDescription .asDefined ());
126+ // cache the size and make sure to avoid iterators here
127+ // this pattern reduces the number of allocations and also the CPU usage
128+ int size = size ();
129+ List <ParameterDescription .InDefinedShape > declaredForms = new ArrayList <ParameterDescription .InDefinedShape >(size );
130+ for (int i = 0 ; i < size ; i ++) {
131+ declaredForms .add (get (i ).asDefined ());
119132 }
120133 return new Explicit <ParameterDescription .InDefinedShape >(declaredForms );
121134 }
@@ -143,6 +156,13 @@ abstract class ForLoadedExecutable<T> extends AbstractBase<ParameterDescription.
143156 */
144157 protected final T executable ;
145158
159+ /**
160+ * The number of parameters of this executable.
161+ * <p>
162+ * It is important to cache it as calling getParameterCount() via the dispatcher has a high cost.
163+ */
164+ protected final int size ;
165+
146166 /**
147167 * The parameter annotation source to query.
148168 */
@@ -156,6 +176,7 @@ abstract class ForLoadedExecutable<T> extends AbstractBase<ParameterDescription.
156176 */
157177 protected ForLoadedExecutable (T executable , ParameterDescription .ForLoadedParameter .ParameterAnnotationSource parameterAnnotationSource ) {
158178 this .executable = executable ;
179+ this .size = EXECUTABLE .getParameterCount (executable );
159180 this .parameterAnnotationSource = parameterAnnotationSource ;
160181 }
161182
@@ -223,7 +244,7 @@ public static ParameterList<ParameterDescription.InDefinedShape> of(Method metho
223244 * {@inheritDoc}
224245 */
225246 public int size () {
226- return EXECUTABLE . getParameterCount ( executable ) ;
247+ return size ;
227248 }
228249
229250 /**
@@ -562,6 +583,11 @@ class TypeSubstituting extends AbstractBase<ParameterDescription.InGenericShape>
562583 */
563584 private final List <? extends ParameterDescription > parameterDescriptions ;
564585
586+ /**
587+ * The number of parameters.
588+ */
589+ private final int size ;
590+
565591 /**
566592 * The visitor to apply to the parameter types before returning them.
567593 */
@@ -579,6 +605,7 @@ public TypeSubstituting(MethodDescription.InGenericShape declaringMethod,
579605 TypeDescription .Generic .Visitor <? extends TypeDescription .Generic > visitor ) {
580606 this .declaringMethod = declaringMethod ;
581607 this .parameterDescriptions = parameterDescriptions ;
608+ this .size = parameterDescriptions .size ();
582609 this .visitor = visitor ;
583610 }
584611
@@ -593,7 +620,7 @@ public ParameterDescription.InGenericShape get(int index) {
593620 * {@inheritDoc}
594621 */
595622 public int size () {
596- return parameterDescriptions . size () ;
623+ return size ;
597624 }
598625 }
599626
0 commit comments