]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/tests/translit/src/com/ibm/icu/dev/test/util/TestUtilities.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / tests / translit / src / com / ibm / icu / dev / test / util / TestUtilities.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 1996-2009, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 package com.ibm.icu.dev.test.util;\r
8 \r
9 import java.text.NumberFormat;\r
10 import java.util.ArrayList;\r
11 import java.util.Arrays;\r
12 import java.util.Collection;\r
13 import java.util.Comparator;\r
14 import java.util.HashMap;\r
15 import java.util.Iterator;\r
16 import java.util.List;\r
17 import java.util.Map;\r
18 import java.util.Random;\r
19 import java.util.Set;\r
20 import java.util.SortedSet;\r
21 import java.util.TreeMap;\r
22 import java.util.TreeSet;\r
23 \r
24 import com.ibm.icu.dev.test.TestBoilerplate;\r
25 import com.ibm.icu.dev.test.TestFmwk;\r
26 import com.ibm.icu.impl.Utility;\r
27 import com.ibm.icu.lang.UCharacter;\r
28 import com.ibm.icu.lang.UProperty;\r
29 import com.ibm.icu.text.UnicodeSet;\r
30 \r
31 public class TestUtilities extends TestFmwk {\r
32     static final int LIMIT = 0x15; // limit to make testing more realistic in terms of collisions\r
33     static final int ITERATIONS = 1000000;\r
34     static final boolean SHOW_PROGRESS = false;\r
35     static final boolean DEBUG = false;\r
36     \r
37     public static void main(String[] args) throws Exception {\r
38         new TestUtilities().run(args);\r
39     }\r
40     \r
41     UnicodeMap map1 = new UnicodeMap();\r
42     Map map2 = new HashMap();\r
43     Map map3 = new TreeMap();\r
44     SortedSet log = new TreeSet();\r
45     static String[] TEST_VALUES = {null, "A", "B", "C", "D", "E", "F"};\r
46     static Random random = new Random(12345);\r
47     \r
48     public void TestUnicodeMap() {\r
49         random.setSeed(12345);\r
50         // do random change to both, then compare\r
51         logln("Comparing against HashMap");\r
52         for (int counter = 0; counter < ITERATIONS; ++counter) {\r
53             int start = random.nextInt(LIMIT);\r
54             String value = TEST_VALUES[random.nextInt(TEST_VALUES.length)];\r
55             String logline = Utility.hex(start) + "\t" + value;\r
56             if (SHOW_PROGRESS) logln(counter + "\t" + logline);\r
57             log.add(logline);\r
58             if (DEBUG && counter == 144) {\r
59                 System.out.println(" debug");\r
60             }\r
61             map1.put(start, value);\r
62             map2.put(new Integer(start), value);\r
63             check(counter);\r
64         }\r
65         checkNext(LIMIT);\r
66         \r
67         logln("Setting General Category");\r
68         map1 = new UnicodeMap();\r
69         map2 = new TreeMap();\r
70         for (int cp = 0; cp <= SET_LIMIT; ++cp) {\r
71               int enumValue = UCharacter.getIntPropertyValue(cp, propEnum);\r
72               //if (enumValue <= 0) continue; // for smaller set\r
73               String value = UCharacter.getPropertyValueName(propEnum,enumValue, UProperty.NameChoice.LONG);\r
74               map1.put(cp, value);\r
75               map2.put(new Integer(cp), value);\r
76         }       \r
77         checkNext(Integer.MAX_VALUE);\r
78 \r
79 \r
80         logln("Comparing General Category");\r
81         check(-1);\r
82         logln("Comparing Values");\r
83         Set values1 = (Set) map1.getAvailableValues(new TreeSet());\r
84         Set values2 = new TreeSet(map2.values());\r
85         if (!TestBoilerplate.verifySetsIdentical(this, values1, values2)) {\r
86             throw new IllegalArgumentException("Halting");\r
87         }\r
88         logln("Comparing Sets");\r
89         for (Iterator it = values1.iterator(); it.hasNext();) {\r
90             Object value = it.next();\r
91             logln(value == null ? "null" : value.toString());\r
92             UnicodeSet set1 = map1.keySet(value);\r
93             UnicodeSet set2 = TestBoilerplate.getSet(map2, value);\r
94             if (!TestBoilerplate.verifySetsIdentical(this, set1, set2)) {\r
95                 throw new IllegalArgumentException("Halting");\r
96             }\r
97         } \r
98         \r
99         logln("Getting Scripts");\r
100         UnicodeMap scripts = ICUPropertyFactory.make().getProperty("script").getUnicodeMap_internal();\r
101         UnicodeMap.Composer composer = new UnicodeMap.Composer() {\r
102             public Object compose(int codepoint, String string, Object a, Object b) {\r
103                 return a.toString() + "_" + b.toString();\r
104             }\r
105         };\r
106         \r
107         logln("Trying Compose");\r
108         UnicodeMap composed = ((UnicodeMap)scripts.cloneAsThawed()).composeWith(map1, composer);\r
109         Object last = "";\r
110         for (int i = 0; i < 0x10FFFF; ++i) {\r
111             Object comp = composed.getValue(i);\r
112             Object gc = map1.getValue(i);\r
113             Object sc = scripts.getValue(i);\r
114             if (!comp.equals(composer.compose(i, null, gc, sc))) {\r
115                 errln("Failed compose at: " + i);\r
116             }\r
117             if (!last.equals(comp)) {\r
118                 logln(Utility.hex(i) + "\t" + comp);\r
119                 last = comp;\r
120             }\r
121         }\r
122 \r
123         // check boilerplate\r
124         List argList = new ArrayList();\r
125         argList.add("TestMain");\r
126         if (params.nothrow) argList.add("-nothrow");\r
127         if (params.verbose) argList.add("-verbose");\r
128         String[] args = new String[argList.size()];\r
129         argList.toArray(args);\r
130         new UnicodeMapBoilerplate().run(args);\r
131          // TODO: the following is not being reached\r
132         new UnicodeSetBoilerplate().run(args);       \r
133     }\r
134     \r
135     public void TestCollectionUtilitySpeed() {\r
136         TreeSet ts1 = new TreeSet();\r
137         TreeSet ts2 = new TreeSet();\r
138         int size = 1000;\r
139         int iterations = 1000;\r
140         String prefix =  "abc";\r
141         String postfix = "nop";\r
142         for (int i = 0; i < size; ++i) {\r
143             ts1.add(prefix + String.valueOf(i) + postfix);\r
144             ts2.add(prefix + String.valueOf(i) + postfix);\r
145         }\r
146         // warm up\r
147         CollectionUtilities.containsAll(ts1, ts2);\r
148         ts1.containsAll(ts2);\r
149 \r
150         timeAndCompare(ts1, ts2, iterations, true, .75);\r
151         // now different sets\r
152         ts1.add("Able");\r
153         timeAndCompare(ts1, ts2, iterations, true, .75);\r
154         timeAndCompare(ts2, ts1, iterations*100, false, 1.05);\r
155     }\r
156 \r
157     private void timeAndCompare(TreeSet ts1, TreeSet ts2, int iterations, boolean expected, double factorOfStandard) {\r
158         double utilityTimeSorted = timeUtilityContainsAll(iterations, ts1, ts2, expected)/(double)iterations;\r
159         double standardTimeSorted = timeStandardContainsAll(iterations, ts1, ts2, expected)/(double)iterations;\r
160         \r
161         if (utilityTimeSorted < standardTimeSorted*factorOfStandard) {\r
162             logln("Sorted: Utility time (" + utilityTimeSorted + ") << Standard duration (" + standardTimeSorted + "); " + 100*(utilityTimeSorted/standardTimeSorted) + "%");\r
163         } else {\r
164             errln("Sorted: Utility time (" + utilityTimeSorted + ") !<< Standard duration (" + standardTimeSorted + "); " + 100*(utilityTimeSorted/standardTimeSorted) + "%");\r
165         }\r
166     }\r
167 \r
168     private long timeStandardContainsAll(int iterations, Set hs1, Set hs2, boolean expected) {\r
169         long standardTime;\r
170         {\r
171             long start, end;\r
172             boolean temp = false;\r
173 \r
174             start = System.currentTimeMillis();\r
175             for (int i = 0; i < iterations; ++i) {\r
176                 temp = hs1.containsAll(hs2);\r
177                 if (temp != expected) {\r
178                     errln("Bad result");\r
179                 }\r
180             }\r
181             end = System.currentTimeMillis();\r
182             standardTime = end - start;\r
183         }\r
184         return standardTime;\r
185     }\r
186 \r
187     private long timeUtilityContainsAll(int iterations, Set hs1, Set hs2, boolean expected) {\r
188         long utilityTime;\r
189         {\r
190             long start, end;\r
191             boolean temp = false;\r
192             start = System.currentTimeMillis();\r
193             for (int i = 0; i < iterations; ++i) {\r
194                 temp = CollectionUtilities.containsAll(hs1, hs2);\r
195                 if (temp != expected) {\r
196                     errln("Bad result");\r
197                 }\r
198             }\r
199             end = System.currentTimeMillis();\r
200             utilityTime = end - start;\r
201         }\r
202         return utilityTime;\r
203     }\r
204     \r
205     public void TestCollectionUtilities() {\r
206         String[][] test = {{"a", "c", "e", "g", "h", "z"}, {"b", "d", "f", "h", "w"}, { "a", "b" }, { "a", "d" }, {"d"}, {}}; // \r
207         int resultMask = 0;\r
208         for (int i = 0; i < test.length; ++i) {\r
209             Collection a = new TreeSet(Arrays.asList(test[i]));\r
210             for (int j = 0; j < test.length; ++j) {\r
211                 Collection b = new TreeSet(Arrays.asList(test[j]));\r
212                 int relation = CollectionUtilities.getContainmentRelation(a, b);\r
213                 resultMask |= (1 << relation);\r
214                 switch (relation) {\r
215                 case CollectionUtilities.ALL_EMPTY:\r
216                     checkContainment(a.size() == 0 && b.size() == 0, a, relation, b);\r
217                     break;\r
218                 case CollectionUtilities.NOT_A_SUPERSET_B:\r
219                     checkContainment(a.size() == 0 && b.size() != 0, a, relation, b);\r
220                     break;\r
221                 case CollectionUtilities.NOT_A_DISJOINT_B:\r
222                     checkContainment(a.equals(b) && a.size() != 0, a, relation, b);\r
223                     break;\r
224                 case CollectionUtilities.NOT_A_SUBSET_B:\r
225                     checkContainment(a.size() != 0 && b.size() == 0, a, relation, b);\r
226                     break;\r
227                 case CollectionUtilities.A_PROPER_SUBSET_OF_B:\r
228                     checkContainment(b.containsAll(a) && !a.equals(b), a, relation, b);\r
229                     break;\r
230                 case CollectionUtilities.NOT_A_EQUALS_B:\r
231                     checkContainment(!CollectionUtilities.containsSome(a, b) && a.size() != 0 && b.size() != 0, a, relation, b);\r
232                     break;\r
233                 case CollectionUtilities.A_PROPER_SUPERSET_B:\r
234                     checkContainment(a.containsAll(b) && !a.equals(b), a, relation, b);\r
235                 break;\r
236                 case CollectionUtilities.A_PROPER_OVERLAPS_B:\r
237                     checkContainment(!b.containsAll(a) && !a.containsAll(b) && CollectionUtilities.containsSome(a, b), a, relation, b);\r
238                 break;\r
239                 }\r
240             }\r
241         }\r
242         if (resultMask != 0xFF) {\r
243             String missing = "";\r
244             for (int i = 0; i < 8; ++i) {\r
245                 if ((resultMask & (1 << i)) == 0) {\r
246                     if (missing.length() != 0) missing += ", ";\r
247                     missing += RelationName[i];\r
248                 }\r
249             }\r
250             errln("Not all ContainmentRelations checked: " + missing);\r
251         }\r
252     }\r
253 \r
254     static final String[] RelationName = {"ALL_EMPTY",\r
255             "NOT_A_SUPERSET_B",\r
256             "NOT_A_DISJOINT_B",\r
257             "NOT_A_SUBSET_B",\r
258             "A_PROPER_SUBSET_OF_B",\r
259             "A_PROPER_DISJOINT_B",\r
260             "A_PROPER_SUPERSET_B",\r
261             "A_PROPER_OVERLAPS_B"};\r
262 \r
263     /**\r
264      *  \r
265      */\r
266     private void checkContainment(boolean c, Collection a, int relation, Collection b) {\r
267         if (!c) {\r
268             errln("Fails relation: " + a + " \t" + RelationName[relation] + " \t" + b);\r
269         }\r
270     }\r
271 \r
272     private void checkNext(int limit) {\r
273         logln("Comparing nextRange");\r
274         UnicodeMapIterator mi = new UnicodeMapIterator(map1);\r
275         Map localMap = new TreeMap();\r
276         while (mi.nextRange()) {\r
277             logln(Utility.hex(mi.codepoint) + ".." + Utility.hex(mi.codepointEnd) + " => " + mi.value);\r
278             for (int i = mi.codepoint; i <= mi.codepointEnd; ++i) {\r
279                 if (i >= limit) continue;\r
280                 localMap.put(new Integer(i), mi.value);\r
281             }\r
282         }\r
283         checkMap(map2, localMap);\r
284         \r
285         logln("Comparing next");\r
286         mi.reset();\r
287         localMap = new TreeMap();\r
288         Object lastValue = new Object();\r
289         while (mi.next()) {\r
290             if (!UnicodeMap.areEqual(lastValue, mi.value)) {\r
291                 // System.out.println("Change: " + Utility.hex(mi.codepoint) + " => " + mi.value);\r
292                 lastValue = mi.value;\r
293             }\r
294             if (mi.codepoint >= limit) continue;\r
295             localMap.put(new Integer(mi.codepoint), mi.value);\r
296         }\r
297         checkMap(map2, localMap);\r
298     }\r
299     \r
300     public void check(int counter) {\r
301         for (int i = 0; i < LIMIT; ++i) {\r
302             Object value1 = map1.getValue(i);\r
303             Object value2 = map2.get(new Integer(i));\r
304             if (!UnicodeMap.areEqual(value1, value2)) {\r
305                 errln(counter + " Difference at " + Utility.hex(i)\r
306                      + "\t UnicodeMap: " + value1\r
307                      + "\t HashMap: " + value2);\r
308                 errln("UnicodeMap: " + map1);\r
309                 errln("Log: " + TestBoilerplate.show(log));\r
310                 errln("HashMap: " + TestBoilerplate.show(map2));\r
311             }\r
312         }\r
313     }\r
314     \r
315     void checkMap(Map m1, Map m2) {\r
316         if (m1.equals(m2)) return;\r
317         StringBuffer buffer = new StringBuffer();\r
318         Set m1entries = m1.entrySet();\r
319         Set m2entries = m2.entrySet();\r
320         getEntries("\r\nIn First, and not Second", m1entries, m2entries, buffer, 20);\r
321         getEntries("\r\nIn Second, and not First", m2entries, m1entries, buffer, 20);\r
322         errln(buffer.toString());\r
323     }\r
324     \r
325     static Comparator ENTRY_COMPARATOR = new Comparator() {\r
326         public int compare(Object o1, Object o2) {\r
327             if (o1 == o2) return 0;\r
328             if (o1 == null) return -1;\r
329             if (o2 == null) return 1;\r
330             Map.Entry a = (Map.Entry) o1;\r
331             Map.Entry b = (Map.Entry) o2;\r
332             int result = compare2(a.getKey(), b.getKey());\r
333             if (result != 0) return result;\r
334             return compare2(a.getValue(), b.getValue());\r
335         }\r
336         private int compare2(Object o1, Object o2) {\r
337             if (o1 == o2) return 0;\r
338             if (o1 == null) return -1;\r
339             if (o2 == null) return 1;\r
340             return ((Comparable)o1).compareTo(o2);\r
341         }\r
342     };\r
343 \r
344     private void getEntries(String title, Set m1entries, Set m2entries, StringBuffer buffer, int limit) {\r
345         Set m1_m2 = new TreeSet(ENTRY_COMPARATOR);\r
346         m1_m2.addAll(m1entries);\r
347         m1_m2.removeAll(m2entries);\r
348         buffer.append(title + ": " + m1_m2.size() + "\r\n");\r
349         for (Iterator it = m1_m2.iterator(); it.hasNext();) {\r
350             if (limit-- < 0) return;\r
351             Map.Entry entry = (Map.Entry) it.next();\r
352             buffer.append(entry.getKey()).append(" => ")\r
353              .append(entry.getValue()).append("\r\n");\r
354         }\r
355     }\r
356     \r
357     static final int SET_LIMIT = 0x10FFFF;\r
358     static final int CHECK_LIMIT = 0xFFFF;\r
359     static final NumberFormat pf = NumberFormat.getPercentInstance();\r
360     static final NumberFormat nf = NumberFormat.getInstance();\r
361     \r
362     public void TestTime() {\r
363         double hashTime, umTime, icuTime, treeTime;\r
364         umTime = checkSetTime(20, 0);\r
365         hashTime = checkSetTime(20, 1);\r
366         logln("Percentage: " + pf.format(hashTime/umTime));\r
367         treeTime = checkSetTime(20, 3);\r
368         logln("Percentage: " + pf.format(treeTime/umTime));\r
369         //logln(map1.toString());\r
370         \r
371         umTime = checkGetTime(1000, 0);\r
372         hashTime = checkGetTime(1000, 1);\r
373         logln("Percentage: " + pf.format(hashTime/umTime));\r
374         icuTime = checkGetTime(1000, 2);\r
375         logln("Percentage: " + pf.format(icuTime/umTime));\r
376         treeTime = checkGetTime(1000, 3);\r
377         logln("Percentage: " + pf.format(treeTime/umTime));\r
378     }\r
379     \r
380     int propEnum = UProperty.GENERAL_CATEGORY;\r
381     \r
382     double checkSetTime(int iterations, int type) {\r
383         _checkSetTime(1,type);\r
384         double result = _checkSetTime(iterations, type);\r
385         logln((type == 0 ? "UnicodeMap" : type == 1 ? "HashMap" : type == 2 ? "ICU" : "TreeMap") + "\t" + nf.format(result));\r
386         return result;\r
387     }\r
388     double _checkSetTime(int iterations, int type) {\r
389         map1 = new UnicodeMap();\r
390         map2 = new HashMap();\r
391         System.gc();\r
392         double start = System.currentTimeMillis();\r
393         for (int j = 0; j < iterations; ++j)\r
394           for (int cp = 0; cp <= SET_LIMIT; ++cp) {\r
395             int enumValue = UCharacter.getIntPropertyValue(cp, propEnum);\r
396             if (enumValue <= 0) continue; // for smaller set\r
397             String value = UCharacter.getPropertyValueName(propEnum,enumValue, UProperty.NameChoice.LONG);\r
398             switch(type) {\r
399             case 0: map1.put(cp, value); break;\r
400             case 1: map2.put(new Integer(cp), value); break;\r
401             case 3: map3.put(new Integer(cp), value); break;\r
402             }\r
403         }\r
404         double end = System.currentTimeMillis();\r
405         return (end-start)/1000/iterations;\r
406     }\r
407     \r
408     double checkGetTime(int iterations, int type) {\r
409         _checkGetTime(1,type);\r
410         double result = _checkGetTime(iterations, type);\r
411         logln((type == 0 ? "UnicodeMap" : type == 1 ? "HashMap" : type == 2 ? "ICU" : "TreeMap") + "\t" + nf.format(result));\r
412         return result;\r
413     }\r
414     double _checkGetTime(int iterations, int type) {\r
415         System.gc();\r
416         double start = System.currentTimeMillis();\r
417         for (int j = 0; j < iterations; ++j)\r
418           for (int cp = 0; cp < CHECK_LIMIT; ++cp) {\r
419             switch (type) {\r
420             case 0: map1.getValue(cp); break;\r
421             case 1: map2.get(new Integer(cp)); break;\r
422             case 2:\r
423                 int enumValue = UCharacter.getIntPropertyValue(cp, propEnum);\r
424                 //if (enumValue <= 0) continue;\r
425                 UCharacter.getPropertyValueName(propEnum,enumValue, UProperty.NameChoice.LONG);\r
426                 break;                \r
427             case 3: map3.get(new Integer(cp)); break;\r
428             }\r
429         }\r
430         double end = System.currentTimeMillis();\r
431         return (end-start)/1000/iterations;\r
432     }\r
433     \r
434     static class UnicodeMapBoilerplate extends TestBoilerplate {\r
435 \r
436         /* \r
437          * @see com.ibm.icu.dev.test.TestBoilerplate#_hasSameBehavior(java.lang.Object, java.lang.Object)\r
438          */\r
439         protected boolean _hasSameBehavior(Object a, Object b) {\r
440             // we are pretty confident in the equals method, so won't bother with this right now.\r
441             return true;\r
442         }\r
443 \r
444         /*\r
445          * @see com.ibm.icu.dev.test.TestBoilerplate#_createTestObject()\r
446          */\r
447         protected boolean _addTestObject(List list) {\r
448             if (list.size() > 30) return false;\r
449             UnicodeMap result = new UnicodeMap();\r
450             for (int i = 0; i < 50; ++i) {\r
451                 int start = random.nextInt(25);\r
452                 String value = TEST_VALUES[random.nextInt(TEST_VALUES.length)];\r
453                 result.put(start, value);\r
454             }\r
455             list.add(result);\r
456             return true;\r
457         }\r
458     }\r
459     \r
460     static class StringBoilerplate extends TestBoilerplate {\r
461 \r
462         /* \r
463          * @see com.ibm.icu.dev.test.TestBoilerplate#_hasSameBehavior(java.lang.Object, java.lang.Object)\r
464          */\r
465         protected boolean _hasSameBehavior(Object a, Object b) {\r
466             // we are pretty confident in the equals method, so won't bother with this right now.\r
467             return true;\r
468         }\r
469 \r
470         /*\r
471          * @see com.ibm.icu.dev.test.TestBoilerplate#_createTestObject()\r
472          */\r
473         protected boolean _addTestObject(List list) {\r
474             if (list.size() > 31) return false;\r
475             StringBuffer result = new StringBuffer();\r
476             for (int i = 0; i < 10; ++i) {\r
477                 result.append((char)random.nextInt(0xFF));\r
478             }\r
479             list.add(result.toString());\r
480             return true;\r
481         }\r
482     }\r
483     \r
484     static class UnicodeSetBoilerplate extends TestBoilerplate {\r
485 \r
486         /* \r
487          * @see com.ibm.icu.dev.test.TestBoilerplate#_hasSameBehavior(java.lang.Object, java.lang.Object)\r
488          */\r
489         protected boolean _hasSameBehavior(Object a, Object b) {\r
490             // we are pretty confident in the equals method, so won't bother with this right now.\r
491             return true;\r
492         }\r
493 \r
494         /*\r
495          * @see com.ibm.icu.dev.test.TestBoilerplate#_createTestObject()\r
496          */\r
497         protected boolean _addTestObject(List list) {\r
498             if (list.size() > 32) return false;\r
499             UnicodeSet result = new UnicodeSet();\r
500             for (int i = 0; i < 50; ++i) {\r
501                 result.add(random.nextInt(100));\r
502             }\r
503             list.add(result.toString());\r
504             return true;\r
505         }\r
506     }\r
507 \r
508 }\r