1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.numbers.examples.jmh.arrays;
19
20
21
22
23
24
25
26
27 enum PivotingStrategy {
28
29
30
31 CENTRAL {
32 @Override
33 int pivotIndex(double[] data, int left, int right, int ignored) {
34 return med(left, right);
35 }
36
37 @Override
38 int[] getSampledIndices(int left, int right, int ignored) {
39 return new int[] {med(left, right)};
40 }
41
42 @Override
43 int samplingEffect() {
44 return UNCHANGED;
45 }
46 },
47
48
49
50 MEDIAN_OF_3 {
51 @Override
52 int pivotIndex(double[] data, int left, int right, int ignored) {
53 return med3(data, left, med(left, right), right);
54 }
55
56 @Override
57 int[] getSampledIndices(int left, int right, int ignored) {
58 return new int[] {left, med(left, right), right};
59 }
60
61 @Override
62 int samplingEffect() {
63 return UNCHANGED;
64 }
65 },
66
67
68
69
70
71
72 MEDIAN_OF_9 {
73 @Override
74 int pivotIndex(double[] data, int left, int right, int ignored) {
75 final int s = (right - left) >>> 3;
76 final int m = med(left, right);
77 final int x = med3(data, left, left + s, left + (s << 1));
78 final double a = data[x];
79 final int y = med3(data, m - s, m, m + s);
80 final double b = data[y];
81 final int z = med3(data, right - (s << 1), right - s, right);
82 return med3(a, b, data[z], x, y, z);
83 }
84
85 @Override
86 int[] getSampledIndices(int left, int right, int ignored) {
87 final int s = (right - left) >>> 3;
88 final int m = med(left, right);
89 return new int[] {
90 left, left + s, left + (s << 1),
91 m - s, m, m + s,
92 right - (s << 1), right - s, right
93 };
94 }
95
96 @Override
97 int samplingEffect() {
98 return UNCHANGED;
99 }
100 },
101
102
103
104
105
106
107
108 DYNAMIC {
109 @Override
110 int pivotIndex(double[] data, int left, int right, int ignored) {
111 if (right - left >= MED_9) {
112 return MEDIAN_OF_9.pivotIndex(data, left, right, ignored);
113 }
114 return MEDIAN_OF_3.pivotIndex(data, left, right, ignored);
115 }
116
117 @Override
118 int[] getSampledIndices(int left, int right, int ignored) {
119 if (right - left >= MED_9) {
120 return MEDIAN_OF_9.getSampledIndices(left, right, ignored);
121 }
122 return MEDIAN_OF_3.getSampledIndices(left, right, ignored);
123 }
124
125 @Override
126 int samplingEffect() {
127 return UNCHANGED;
128 }
129 },
130
131
132
133
134
135
136
137
138 MEDIAN_OF_5 {
139 @Override
140 int pivotIndex(double[] data, int left, int right, int ignored) {
141
142
143
144 final int len = right - left;
145 final int sixth = 1 + (len >>> 3) + (len >>> 5) + (len >>> 6);
146
147
148 final int p3 = left + (len >>> 1);
149 final int p2 = p3 - sixth;
150 final int p1 = p2 - sixth;
151 final int p4 = p3 + sixth;
152 final int p5 = p4 + sixth;
153 return Sorting.median5(data, p1, p2, p3, p4, p5);
154 }
155
156 @Override
157 int[] getSampledIndices(int left, int right, int ignored) {
158 final int len = right - left;
159 final int sixth = 1 + (len >>> 3) + (len >>> 5) + (len >>> 6);
160 final int p3 = left + (len >>> 1);
161 final int p2 = p3 - sixth;
162 final int p1 = p2 - sixth;
163 final int p4 = p3 + sixth;
164 final int p5 = p4 + sixth;
165 return new int[] {p1, p2, p3, p4, p5};
166 }
167
168 @Override
169 int samplingEffect() {
170 return PARTIAL_SORT;
171 }
172 },
173
174
175
176
177
178
179
180
181 MEDIAN_OF_5B {
182 @Override
183 int pivotIndex(double[] data, int left, int right, int ignored) {
184
185
186
187 final int len = right - left;
188 final int seventh = 1 + (len >>> 3) + (len >>> 6);
189 final int p3 = left + (len >>> 1);
190 final int p2 = p3 - seventh;
191 final int p1 = p2 - seventh;
192 final int p4 = p3 + seventh;
193 final int p5 = p4 + seventh;
194 Sorting.sort4(data, p1, p2, p4, p5);
195
196 if (data[p3] < data[p2]) {
197 return p2;
198 }
199 return data[p3] > data[p4] ? p4 : p3;
200 }
201
202 @Override
203 int[] getSampledIndices(int left, int right, int ignored) {
204 final int len = right - left;
205 final int seventh = 1 + (len >>> 3) + (len >>> 6);
206 final int p3 = left + (len >>> 1);
207 final int p2 = p3 - seventh;
208 final int p1 = p2 - seventh;
209 final int p4 = p3 + seventh;
210 final int p5 = p4 + seventh;
211 return new int[] {p1, p2, p3, p4, p5};
212 }
213
214 @Override
215 int samplingEffect() {
216 return PARTIAL_SORT;
217 }
218 },
219
220
221
222 TARGET {
223 @Override
224 int pivotIndex(double[] data, int left, int right, int k) {
225 return k;
226 }
227
228 @Override
229 int[] getSampledIndices(int left, int right, int k) {
230 return new int[] {k};
231 }
232
233 @Override
234 int samplingEffect() {
235 return UNCHANGED;
236 }
237 };
238
239
240 static final int UNCHANGED = 0;
241
242 static final int PARTIAL_SORT = 0x1;
243
244 static final int SORT = 0x2;
245
246 private static final int MED_9 = 40;
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 private static int med(int left, int right) {
263 return (left + right + 1) >>> 1;
264 }
265
266
267
268
269
270
271
272
273
274
275 private static int med3(double[] data, int i, int j, int k) {
276 return med3(data[i], data[j], data[k], i, j, k);
277 }
278
279
280
281
282
283
284
285
286
287
288
289
290 private static int med3(double a, double b, double c, int ia, int ib, int ic) {
291 if (a < b) {
292 if (b < c) {
293 return ib;
294 }
295 return a < c ? ic : ia;
296 }
297 if (b > c) {
298 return ib;
299 }
300 return a > c ? ic : ia;
301 }
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320 abstract int pivotIndex(double[] data, int left, int right, int k);
321
322
323
324
325
326
327
328
329
330
331
332 abstract int[] getSampledIndices(int left, int right, int k);
333
334
335
336
337
338
339
340
341
342
343
344 abstract int samplingEffect();
345 }