module candy.misc.dstest; import tango.io.stream.Lines; import tango.io.device.File; import tango.time.StopWatch; import tango.io.Stdout; import tango.core.Memory; import tango.core.Array; import tango.util.collection.HashMap; import tango.util.collection.TreeMap; import candy.util.array; import candy.util.tst; public struct TestPart { char[] name; void delegate() run; } public class Test { public char[] name; public TestPart[] parts; } public static T median(T)(T[] values) { assert(values.length > 0); uint mid = values.length / 2; return (values.length % 2 == 0) ? ((values[mid - 1] + values[mid]) / 2) : values[mid]; } public static T mean(T)(T[] values) { T total = 0; foreach(value; values) total += value; return total / values.length; } public void doTest(char[] sectionName, uint iterations, Test[] tests) { Stdout.format("Running tests for {0}...", sectionName).newline(); Stdout("Test Part Mean Median Max").newline(); Stdout("---- ---- ---- ------ ---").newline(); foreach(test; tests) { double[][] times = new double[][test.parts.length]; foreach(j, part; test.parts) times[j] = new double[iterations]; for(int i = 0; i < iterations; i++) { foreach(j, part; test.parts) { sw.start(); part.run(); times[j][i] = sw.stop(); } GC.collect(); } foreach(j, part; test.parts) { times[j].sort(); Stdout.format("{0,-20}{1,-20}{2,-10:f4}{3,-10:f4}{4,-10:f4}", test.name, part.name, mean(times[j]), median(times[j]), times[j][$ - 1]).newline(); } } } private StopWatch sw; public const uint SIZE = 1024 * 1000; public const uint ITERS = 9; public char[][] words, words2; public int main() { Stdout.flush(true); generateDictionary(); GC.collect(); Test[] dictTests; dictTests ~= new DictTest!("TST", TernaryTree!(char, bool), "new TernaryTree!(char, bool)"); dictTests ~= new DictTest!("HashMap", HashMap!(char[], bool), "new HashMap!(char[], bool)"); dictTests ~= new DictTest!("TreeMap", TreeMap!(char[], bool), "new TreeMap!(char[], bool)"); dictTests ~= new DictTest!("AssocArray", bool[char[]], "", "dict[word] = true;", "result = dict[word];"); doTest("dictionaries", ITERS, dictTests); return 0; } public void generateDictionary() { Array!(char[]) temp; foreach(line; new Lines!(char)(new File("wordsEn.txt"))) if(line.length) temp ~= line; words = temp.toArray(); words2 = temp.toArray().dup; words.shuffle(); words2.shuffle(); } public class DictTest(char[] testName, T, char[] create, char[] insertElem = "dict.add(word, true);", char[] getElem = "dict.get(word, result);") : Test { private T dict; public this() { dict = null; name = testName; parts = [TestPart("Insertion", &insert), TestPart("Iteration", &iterate), TestPart("Lookup", &lookup)]; } public void insert() { static if(create.length) dict = mixin(create); foreach(word; words) mixin(insertElem); } public void iterate() { foreach(word, check; dict) if(!check) throw new Exception(""); } public void lookup() { foreach(word; words2) { bool result; mixin(getElem); if(!result) throw new Exception(""); } dict = null; } }