@@ -79,7 +79,11 @@ abstract class AbstractBase<S extends ParameterDescription> extends FilterableLi
79
79
* {@inheritDoc}
80
80
*/
81
81
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 );
83
87
if (!parameterDescription .isNamed () || !parameterDescription .hasModifiers ()) {
84
88
return false ;
85
89
}
@@ -91,9 +95,12 @@ public boolean hasExplicitMetaData() {
91
95
* {@inheritDoc}
92
96
*/
93
97
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 ));
97
104
}
98
105
return new ByteCodeElement .Token .TokenList <ParameterDescription .Token >(tokens );
99
106
}
@@ -102,9 +109,12 @@ public ByteCodeElement.Token.TokenList<ParameterDescription.Token> asTokenList(E
102
109
* {@inheritDoc}
103
110
*/
104
111
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 ());
108
118
}
109
119
return new TypeList .Generic .Explicit (types );
110
120
}
@@ -113,9 +123,12 @@ public TypeList.Generic asTypeList() {
113
123
* {@inheritDoc}
114
124
*/
115
125
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 ());
119
132
}
120
133
return new Explicit <ParameterDescription .InDefinedShape >(declaredForms );
121
134
}
@@ -143,6 +156,13 @@ abstract class ForLoadedExecutable<T> extends AbstractBase<ParameterDescription.
143
156
*/
144
157
protected final T executable ;
145
158
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
+
146
166
/**
147
167
* The parameter annotation source to query.
148
168
*/
@@ -156,6 +176,7 @@ abstract class ForLoadedExecutable<T> extends AbstractBase<ParameterDescription.
156
176
*/
157
177
protected ForLoadedExecutable (T executable , ParameterDescription .ForLoadedParameter .ParameterAnnotationSource parameterAnnotationSource ) {
158
178
this .executable = executable ;
179
+ this .size = EXECUTABLE .getParameterCount (executable );
159
180
this .parameterAnnotationSource = parameterAnnotationSource ;
160
181
}
161
182
@@ -223,7 +244,7 @@ public static ParameterList<ParameterDescription.InDefinedShape> of(Method metho
223
244
* {@inheritDoc}
224
245
*/
225
246
public int size () {
226
- return EXECUTABLE . getParameterCount ( executable ) ;
247
+ return size ;
227
248
}
228
249
229
250
/**
@@ -562,6 +583,11 @@ class TypeSubstituting extends AbstractBase<ParameterDescription.InGenericShape>
562
583
*/
563
584
private final List <? extends ParameterDescription > parameterDescriptions ;
564
585
586
+ /**
587
+ * The number of parameters.
588
+ */
589
+ private final int size ;
590
+
565
591
/**
566
592
* The visitor to apply to the parameter types before returning them.
567
593
*/
@@ -579,6 +605,7 @@ public TypeSubstituting(MethodDescription.InGenericShape declaringMethod,
579
605
TypeDescription .Generic .Visitor <? extends TypeDescription .Generic > visitor ) {
580
606
this .declaringMethod = declaringMethod ;
581
607
this .parameterDescriptions = parameterDescriptions ;
608
+ this .size = parameterDescriptions .size ();
582
609
this .visitor = visitor ;
583
610
}
584
611
@@ -593,7 +620,7 @@ public ParameterDescription.InGenericShape get(int index) {
593
620
* {@inheritDoc}
594
621
*/
595
622
public int size () {
596
- return parameterDescriptions . size () ;
623
+ return size ;
597
624
}
598
625
}
599
626
0 commit comments