ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/MapCheck.java
Revision: 1.1
Committed: Mon May 2 19:19:38 2005 UTC (19 years ago) by dl
Branch: MAIN
Log Message:
Put misc performance tests into CVS

File Contents

# Content
1 /**
2 * @test
3 * @synopsis Times and checks basic map operations
4 */
5 import java.util.*;
6 import java.io.*;
7
8 public class MapCheck {
9
10 static final int absentSize = 1 << 17;
11 static final int absentMask = absentSize - 1;
12 static Object[] absent = new Object[absentSize];
13
14 static final Object MISSING = new Object();
15
16 static TestTimer timer = new TestTimer();
17
18 static void reallyAssert(boolean b) {
19 if (!b) throw new Error("Failed Assertion");
20 }
21
22 public static void main(String[] args) throws Exception {
23 Class mapClass = java.util.concurrent.ConcurrentHashMap.class;
24 int numTests = 50;
25 int size = 50000;
26
27 if (args.length > 0) {
28 try {
29 mapClass = Class.forName(args[0]);
30 } catch(ClassNotFoundException e) {
31 throw new RuntimeException("Class " + args[0] + " not found.");
32 }
33 }
34
35
36 if (args.length > 1)
37 numTests = Integer.parseInt(args[1]);
38
39 if (args.length > 2)
40 size = Integer.parseInt(args[2]);
41
42 boolean doSerializeTest = args.length > 3;
43
44 System.out.println("Testing " + mapClass.getName() + " trials: " + numTests + " size: " + size);
45
46 for (int i = 0; i < absentSize; ++i) absent[i] = new Object();
47
48 Object[] key = new Object[size];
49 for (int i = 0; i < size; ++i) key[i] = new Object();
50
51 forceMem(size * 8);
52
53 for (int rep = 0; rep < numTests; ++rep) {
54 runTest(newMap(mapClass), key);
55 }
56
57 TestTimer.printStats();
58
59
60 if (doSerializeTest)
61 stest(newMap(mapClass), size);
62 }
63
64 static Map newMap(Class cl) {
65 try {
66 Map m = (Map)cl.newInstance();
67 return m;
68 } catch(Exception e) {
69 throw new RuntimeException("Can't instantiate " + cl + ": " + e);
70 }
71 }
72
73
74 static void runTest(Map s, Object[] key) {
75 shuffle(key);
76 int size = key.length;
77 long startTime = System.currentTimeMillis();
78 test(s, key);
79 long time = System.currentTimeMillis() - startTime;
80 }
81
82 static void forceMem(int n) {
83 // force enough memory
84 Long[] junk = new Long[n];
85 for (int i = 0; i < junk.length; ++i) junk[i] = new Long(i);
86 int sum = 0;
87 for (int i = 0; i < junk.length; ++i)
88 sum += (int)(junk[i].longValue() + i);
89 if (sum == 0) System.out.println("Useless number = " + sum);
90 junk = null;
91 // System.gc();
92 }
93
94
95 static void t1(String nm, int n, Map s, Object[] key, int expect) {
96 int sum = 0;
97 int iters = 4;
98 timer.start(nm, n * iters);
99 for (int j = 0; j < iters; ++j) {
100 for (int i = 0; i < n; i++) {
101 if (s.get(key[i]) != null) ++sum;
102 }
103 }
104 timer.finish();
105 reallyAssert (sum == expect * iters);
106 }
107
108 static void t2(String nm, int n, Map s, Object[] key, int expect) {
109 int sum = 0;
110 timer.start(nm, n);
111 for (int i = 0; i < n; i++) {
112 if (s.remove(key[i]) != null) ++sum;
113 }
114 timer.finish();
115 reallyAssert (sum == expect);
116 }
117
118 static void t3(String nm, int n, Map s, Object[] key, int expect) {
119 int sum = 0;
120 timer.start(nm, n);
121 for (int i = 0; i < n; i++) {
122 if (s.put(key[i], absent[i & absentMask]) == null) ++sum;
123 }
124 timer.finish();
125 reallyAssert (sum == expect);
126 }
127
128 static void t4(String nm, int n, Map s, Object[] key, int expect) {
129 int sum = 0;
130 timer.start(nm, n);
131 for (int i = 0; i < n; i++) {
132 if (s.containsKey(key[i])) ++sum;
133 }
134 timer.finish();
135 reallyAssert (sum == expect);
136 }
137
138 static void t5(String nm, int n, Map s, Object[] key, int expect) {
139 int sum = 0;
140 timer.start(nm, n/2);
141 for (int i = n-2; i >= 0; i-=2) {
142 if (s.remove(key[i]) != null) ++sum;
143 }
144 timer.finish();
145 reallyAssert (sum == expect);
146 }
147
148 static void t6(String nm, int n, Map s, Object[] k1, Object[] k2) {
149 int sum = 0;
150 timer.start(nm, n * 2);
151 for (int i = 0; i < n; i++) {
152 if (s.get(k1[i]) != null) ++sum;
153 if (s.get(k2[i & absentMask]) != null) ++sum;
154 }
155 timer.finish();
156 reallyAssert (sum == n);
157 }
158
159 static void t7(String nm, int n, Map s, Object[] k1, Object[] k2) {
160 int sum = 0;
161 timer.start(nm, n * 2);
162 for (int i = 0; i < n; i++) {
163 if (s.containsKey(k1[i])) ++sum;
164 if (s.containsKey(k2[i & absentMask])) ++sum;
165 }
166 timer.finish();
167 reallyAssert (sum == n);
168 }
169
170 static void t8(String nm, int n, Map s, Object[] key, int expect) {
171 int sum = 0;
172 timer.start(nm, n);
173 for (int i = 0; i < n; i++) {
174 if (s.get(key[i]) != null) ++sum;
175 }
176 timer.finish();
177 reallyAssert (sum == expect);
178 }
179
180
181 static void t9(Map s) {
182 int sum = 0;
183 int iters = 20;
184 timer.start("ContainsValue (/n) ", iters * s.size());
185 int step = absentSize / iters;
186 for (int i = 0; i < absentSize; i += step)
187 if (s.containsValue(absent[i])) ++sum;
188 timer.finish();
189 reallyAssert (sum != 0);
190 }
191
192
193 static void ktest(Map s, int size, Object[] key) {
194 timer.start("ContainsKey ", size);
195 Set ks = s.keySet();
196 int sum = 0;
197 for (int i = 0; i < size; i++) {
198 if (ks.contains(key[i])) ++sum;
199 }
200 timer.finish();
201 reallyAssert (sum == size);
202 }
203
204
205 static void ittest1(Map s, int size) {
206 int sum = 0;
207 timer.start("Iter Key ", size);
208 for (Iterator it = s.keySet().iterator(); it.hasNext(); ) {
209 if(it.next() != MISSING)
210 ++sum;
211 }
212 timer.finish();
213 reallyAssert (sum == size);
214 }
215
216 static void ittest2(Map s, int size) {
217 int sum = 0;
218 timer.start("Iter Value ", size);
219 for (Iterator it = s.values().iterator(); it.hasNext(); ) {
220 if(it.next() != MISSING)
221 ++sum;
222 }
223 timer.finish();
224 reallyAssert (sum == size);
225 }
226 static void ittest3(Map s, int size) {
227 int sum = 0;
228 timer.start("Iter Entry ", size);
229 for (Iterator it = s.entrySet().iterator(); it.hasNext(); ) {
230 if(it.next() != MISSING)
231 ++sum;
232 }
233 timer.finish();
234 reallyAssert (sum == size);
235 }
236
237 static void ittest4(Map s, int size, int pos) {
238 IdentityHashMap seen = new IdentityHashMap(size);
239 reallyAssert (s.size() == size);
240 int sum = 0;
241 timer.start("Iter XEntry ", size);
242 Iterator it = s.entrySet().iterator();
243 Object k = null;
244 Object v = null;
245 for (int i = 0; i < size-pos; ++i) {
246 Map.Entry x = (Map.Entry)(it.next());
247 k = x.getKey();
248 v = x.getValue();
249 seen.put(k, k);
250 if (x != MISSING)
251 ++sum;
252 }
253 reallyAssert (s.containsKey(k));
254 it.remove();
255 reallyAssert (!s.containsKey(k));
256 while (it.hasNext()) {
257 Map.Entry x = (Map.Entry)(it.next());
258 Object k2 = x.getKey();
259 seen.put(k2, k2);
260 if (x != MISSING)
261 ++sum;
262 }
263
264 reallyAssert (s.size() == size-1);
265 s.put(k, v);
266 reallyAssert (seen.size() == size);
267 timer.finish();
268 reallyAssert (sum == size);
269 reallyAssert (s.size() == size);
270 }
271
272
273 static void ittest(Map s, int size) {
274 ittest1(s, size);
275 ittest2(s, size);
276 ittest3(s, size);
277 // for (int i = 0; i < size-1; ++i)
278 // ittest4(s, size, i);
279 }
280
281 static void entest1(Hashtable ht, int size) {
282 int sum = 0;
283
284 timer.start("Iter Enumeration Key ", size);
285 for (Enumeration en = ht.keys(); en.hasMoreElements(); ) {
286 if (en.nextElement() != MISSING)
287 ++sum;
288 }
289 timer.finish();
290 reallyAssert (sum == size);
291 }
292
293 static void entest2(Hashtable ht, int size) {
294 int sum = 0;
295 timer.start("Iter Enumeration Value ", size);
296 for (Enumeration en = ht.elements(); en.hasMoreElements(); ) {
297 if (en.nextElement() != MISSING)
298 ++sum;
299 }
300 timer.finish();
301 reallyAssert (sum == size);
302 }
303
304
305 static void entest3(Hashtable ht, int size) {
306 int sum = 0;
307
308 timer.start("Iterf Enumeration Key ", size);
309 Enumeration en = ht.keys();
310 for (int i = 0; i < size; ++i) {
311 if (en.nextElement() != MISSING)
312 ++sum;
313 }
314 timer.finish();
315 reallyAssert (sum == size);
316 }
317
318 static void entest4(Hashtable ht, int size) {
319 int sum = 0;
320 timer.start("Iterf Enumeration Value", size);
321 Enumeration en = ht.elements();
322 for (int i = 0; i < size; ++i) {
323 if (en.nextElement() != MISSING)
324 ++sum;
325 }
326 timer.finish();
327 reallyAssert (sum == size);
328 }
329
330 static void entest(Map s, int size) {
331 if (s instanceof Hashtable) {
332 Hashtable ht = (Hashtable)s;
333 // entest3(ht, size);
334 // entest4(ht, size);
335 entest1(ht, size);
336 entest2(ht, size);
337 entest1(ht, size);
338 entest2(ht, size);
339 entest1(ht, size);
340 entest2(ht, size);
341 }
342 }
343
344 static void rtest(Map s, int size) {
345 timer.start("Remove (iterator) ", size);
346 for (Iterator it = s.keySet().iterator(); it.hasNext(); ) {
347 it.next();
348 it.remove();
349 }
350 timer.finish();
351 }
352
353 static void rvtest(Map s, int size) {
354 timer.start("Remove (iterator) ", size);
355 for (Iterator it = s.values().iterator(); it.hasNext(); ) {
356 it.next();
357 it.remove();
358 }
359 timer.finish();
360 }
361
362
363 static void dtest(Map s, int size, Object[] key) {
364 timer.start("Put (putAll) ", size * 2);
365 Map s2 = null;
366 try {
367 s2 = (Map) (s.getClass().newInstance());
368 s2.putAll(s);
369 }
370 catch (Exception e) { e.printStackTrace(); return; }
371 timer.finish();
372
373 timer.start("Iter Equals ", size * 2);
374 boolean eqt = s2.equals(s) && s.equals(s2);
375 reallyAssert (eqt);
376 timer.finish();
377
378 timer.start("Iter HashCode ", size * 2);
379 int shc = s.hashCode();
380 int s2hc = s2.hashCode();
381 reallyAssert (shc == s2hc);
382 timer.finish();
383
384 timer.start("Put (present) ", size);
385 s2.putAll(s);
386 timer.finish();
387
388 timer.start("Iter EntrySet contains ", size * 2);
389 Set es2 = s2.entrySet();
390 int sum = 0;
391 for (Iterator i1 = s.entrySet().iterator(); i1.hasNext(); ) {
392 Object entry = i1.next();
393 if (es2.contains(entry)) ++sum;
394 }
395 timer.finish();
396 reallyAssert (sum == size);
397
398 t6("Get ", size, s2, key, absent);
399
400 Object hold = s2.get(key[size-1]);
401 s2.put(key[size-1], absent[0]);
402 timer.start("Iter Equals ", size * 2);
403 eqt = s2.equals(s) && s.equals(s2);
404 reallyAssert (!eqt);
405 timer.finish();
406
407 timer.start("Iter HashCode ", size * 2);
408 int s1h = s.hashCode();
409 int s2h = s2.hashCode();
410 reallyAssert (s1h != s2h);
411 timer.finish();
412
413 s2.put(key[size-1], hold);
414 timer.start("Remove (iterator) ", size * 2);
415 Iterator s2i = s2.entrySet().iterator();
416 Set es = s.entrySet();
417 while (s2i.hasNext())
418 es.remove(s2i.next());
419 timer.finish();
420
421 reallyAssert (s.isEmpty());
422
423 timer.start("Clear ", size);
424 s2.clear();
425 timer.finish();
426 reallyAssert (s2.isEmpty() && s.isEmpty());
427 }
428
429 static void stest(Map s, int size) throws Exception {
430 if (!(s instanceof Serializable))
431 return;
432 System.out.print("Serialize : ");
433
434 for (int i = 0; i < size; i++) {
435 s.put(new Integer(i), Boolean.TRUE);
436 }
437
438 long startTime = System.currentTimeMillis();
439
440 FileOutputStream fs = new FileOutputStream("MapCheck.dat");
441 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(fs));
442 out.writeObject(s);
443 out.close();
444
445 FileInputStream is = new FileInputStream("MapCheck.dat");
446 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(is));
447 Map m = (Map)in.readObject();
448
449 long endTime = System.currentTimeMillis();
450 long time = endTime - startTime;
451
452 System.out.print(time + "ms");
453
454 if (s instanceof IdentityHashMap) return;
455 reallyAssert (s.equals(m));
456 }
457
458
459 static void test(Map s, Object[] key) {
460 int size = key.length;
461
462 t3("Put (absent) ", size, s, key, size);
463 t3("Put (present) ", size, s, key, 0);
464 t7("ContainsKey ", size, s, key, absent);
465 t4("ContainsKey ", size, s, key, size);
466 ktest(s, size, key);
467 t4("ContainsKey ", absentSize, s, absent, 0);
468 t6("Get ", size, s, key, absent);
469 t1("Get (present) ", size, s, key, size);
470 t1("Get (absent) ", absentSize, s, absent, 0);
471 t2("Remove (absent) ", absentSize, s, absent, 0);
472 t5("Remove (present) ", size, s, key, size / 2);
473 t3("Put (half present) ", size, s, key, size / 2);
474
475 ittest(s, size);
476 entest(s, size);
477 t9(s);
478 rtest(s, size);
479
480 t4("ContainsKey ", size, s, key, 0);
481 t2("Remove (absent) ", size, s, key, 0);
482 t3("Put (presized) ", size, s, key, size);
483 dtest(s, size, key);
484 }
485
486 static class TestTimer {
487 private String name;
488 private long numOps;
489 private long startTime;
490 private String cname;
491
492 static final java.util.TreeMap accum = new java.util.TreeMap();
493
494 static void printStats() {
495 for (Iterator it = accum.entrySet().iterator(); it.hasNext(); ) {
496 Map.Entry e = (Map.Entry)(it.next());
497 Stats stats = ((Stats)(e.getValue()));
498 int n = stats.number;
499 double t;
500 if (n > 0)
501 t = stats.sum / n;
502 else
503 t = stats.least;
504 long nano = Math.round(1000000.0 * t);
505 System.out.println(e.getKey() + ": " + nano);
506 }
507 }
508
509 void start(String name, long numOps) {
510 this.name = name;
511 this.cname = classify();
512 this.numOps = numOps;
513 startTime = System.currentTimeMillis();
514 }
515
516
517 String classify() {
518 if (name.startsWith("Get"))
519 return "Get ";
520 else if (name.startsWith("Put"))
521 return "Put ";
522 else if (name.startsWith("Remove"))
523 return "Remove ";
524 else if (name.startsWith("Iter"))
525 return "Iter ";
526 else
527 return null;
528 }
529
530 void finish() {
531 long endTime = System.currentTimeMillis();
532 long time = endTime - startTime;
533 double timePerOp = ((double)time)/numOps;
534
535 Object st = accum.get(name);
536 if (st == null)
537 accum.put(name, new Stats(timePerOp));
538 else {
539 Stats stats = (Stats) st;
540 stats.sum += timePerOp;
541 stats.number++;
542 if (timePerOp < stats.least) stats.least = timePerOp;
543 }
544
545 if (cname != null) {
546 st = accum.get(cname);
547 if (st == null)
548 accum.put(cname, new Stats(timePerOp));
549 else {
550 Stats stats = (Stats) st;
551 stats.sum += timePerOp;
552 stats.number++;
553 if (timePerOp < stats.least) stats.least = timePerOp;
554 }
555 }
556
557 }
558
559 }
560
561 static class Stats {
562 double sum = 0;
563 double least;
564 int number = 0;
565 Stats(double t) { least = t; }
566 }
567
568 static Random rng = new Random();
569
570 static void shuffle(Object[] keys) {
571 int size = keys.length;
572 for (int i=size; i>1; i--) {
573 int r = rng.nextInt(i);
574 Object t = keys[i-1];
575 keys[i-1] = keys[r];
576 keys[r] = t;
577 }
578 }
579
580 }
581