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

# User Rev Content
1 dl 1.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