void Optimize(SubString key, Node current, Node parent) { if (!current.Value.HasValue && current.Children.Count == 1) { KeyValuePair <SubString, Node> pair = current.Children.First(); Node node = pair.Value; parent.Children.Remove(key); var newKey = new SubString(key.ToString() + pair.Key.ToString()); node.PrefixLength = newKey.Length; parent.Children.Add(newKey, node); this.Optimize(newKey, node, parent); } else { foreach (KeyValuePair <SubString, Node> child in current.Children.ToArray()) { this.Optimize(child.Key, child.Value, current); } } }
public bool TryGetValue(SubString key, out int value) { Node current = this.root; do { Node newCurrent; if (current.Children.TryGetValue(key, out newCurrent)) { current = newCurrent; int matchRemainder = key.Length - current.PrefixLength; if (matchRemainder == 0) { if (current.Value.HasValue) { value = current.Value.Value; return(true); } else { value = default(int); return(false); } } key = key.Substring(current.PrefixLength, matchRemainder); } else { value = default(int); return(false); } }while (current.Children.Count > 0); value = default(int); return(false); }
public static long Run() { long ran = 0; const int Iterations = 15 * 1000 * 1000; const string Value = "suubscriptionkey345keygfql3i4ufgdf3187632541236451287364182345192e6rgiquf4ro8q2trp9q83yrr34r4gw45g34fw3sfdsfr34rq34r34r3fq34fq3fraq34rq34rq3rfqeeeq2344234rq34fq3rfq2fq35yw45yw4frdaewdawrt35tq34aededksetroifuaewpgftiuaetfiawtefoiuwayefyagwieuftwae"; var comparer = new OrdinalIgnoreCaseSubStringComparer(); for (int matchLength = 2; matchLength <= 20; matchLength += 2) { //for (int matchCount = 1; matchCount <= 10; matchCount++) for (int matchCount = 10; matchCount <= 10; matchCount++) { Tuple <SubString, int>[] matches = Enumerable.Range(1, matchCount).Select(i => new SubString(Value, i, matchLength)).Select(x => Tuple.Create(x, 1)).ToArray(); var lookupArray = new Tuple <SubString, int> [matchLength][]; lookupArray[matchLength - 1] = matches; var map = new Dictionary <SubString, int>(comparer); var mapGuard = new Dictionary <Tuple <char, char>, int>(); foreach (Tuple <SubString, int> match in matches) { mapGuard.Add(Tuple.Create(char.ToLowerInvariant(match.Item1[0]), char.ToLowerInvariant(match.Item1[match.Item1.Length - 1])), 1); map.Add(match.Item1, match.Item2); } var mapSorted = new SortedList <SubString, int>(map, comparer); //var tree = new SubStringTree(map); //CodeTimer.Time(true, FormatTitle("sub tre", matchLength, matchCount), Iterations, () => //{ // var candidateA = new SubString(Value, matchCount, matchLength); // int v; // tree.TryGetValue(candidateA, out v); //}); var mapS = new Dictionary <string, int>(map.ToDictionary(s => s.Key.ToString(), s => s.Value), StringComparer.OrdinalIgnoreCase); CodeTimer.Time(true, FormatTitle("str lkp", matchLength, matchCount), Iterations, () => { string candidateS = Value.Substring(matchCount, matchLength); int v; mapS.TryGetValue(candidateS, out v); }); //var matchesS = matches.Select(x => Tuple.Create(x.Item1.ToString(), x.Item2)).ToArray(); //CodeTimer.Time(true, FormatTitle("str cmp", matchLength, matchCount), Iterations, () => //{ // var candidateS = Value.Substring(matchCount, matchLength); // var lookupList = matchesS; // foreach (var matchL in lookupList) // { // var matchString = matchL.Item1; // //int length = matchString.Length; // //if (length > 2) // //{ // // if (OrdinalIgnoreCaseSubStringComparer.ToLower(matchString[0]) != OrdinalIgnoreCaseSubStringComparer.ToLower(candidateS[0]) // // || OrdinalIgnoreCaseSubStringComparer.ToLower(matchString[length - 1]) != OrdinalIgnoreCaseSubStringComparer.ToLower(candidateS[length - 1])) // // { // // continue; // // } // //} // if (StringComparer.OrdinalIgnoreCase.Equals(candidateS, matchString)) // //if (StringComparer.OrdinalIgnoreCase.Equals(candidateS.Substring(1, length - 2), matchString.Substring(1, length - 2))) // { // break; // } // } //}); //CodeTimer.Time(true, FormatTitle("sub cmp", matchLength, matchCount), Iterations, () => //{ // var candidate = new SubString(Value, matchCount, matchLength); // Tuple<SubString, int>[] lookupList = lookupArray[candidate.Length - 1]; // if (lookupList != null) // { // foreach (var matchL in lookupList) // { // SubString matchString = matchL.Item1; // //int length = matchString.Length; // //if (length > 2) // //{ // // if (OrdinalIgnoreCaseSubStringComparer.ToLower(matchString[0]) != OrdinalIgnoreCaseSubStringComparer.ToLower(candidate[0]) // // || OrdinalIgnoreCaseSubStringComparer.ToLower(matchString[length - 1]) != OrdinalIgnoreCaseSubStringComparer.ToLower(candidate[length - 1])) // // { // // continue; // // } // //} // if (comparer.Equals(candidate, matchString)) // //if (comparer.Equals(candidate.Substring(1, length - 2), matchL.Substring(1, length - 2))) // { // break; // } // } // } //}); CodeTimer.Time(true, FormatTitle("sub lkp", matchLength, matchCount), Iterations, () => { var candidateA = new SubString(Value, matchCount, matchLength); int v; map.TryGetValue(candidateA, out v); }); //CodeTimer.Time(true, FormatTitle("sub srt", matchLength, matchCount), Iterations, () => //{ // var candidateA = new SubString(Value, matchCount, matchLength); // int v; // mapSorted.TryGetValue(candidateA, out v); //}); } } return(ran); }
public static unsafe long Run() { long ran = 0; const int iterations = 10 * 1000 * 1000; string value = "?subscription-key=345&key=gfql3i4ufgdf3"; string value2 = "?key=gfql3i4ufgdf3&subscription-key=345"; var subValue = new SubString(value, 0, value.Length); //byte[] valueBytes = Encoding.Unicode.GetBytes(value); //Console.WriteLine(value.GetHashCode()); //Console.WriteLine(subValue.GetHashCode()); //CodeTimer.Time(true, "string.GetHashCode()", iterations, () => { value.GetHashCode(); }); //CodeTimer.Time(true, "SubString.GetHashCode()", iterations, () => { subValue.GetHashCode(); }); var subString = new SubString(value, 1, 16); Console.WriteLine(subString.ToString() + ":" + subString.GetHashCode()); subString = new SubString(value, 22, 3); Console.WriteLine(subString.ToString() + ":" + subString.GetHashCode()); subString = new SubString(value2, 19, 16); Console.WriteLine(subString.ToString() + ":" + subString.GetHashCode()); subString = new SubString(value2, 1, 3); Console.WriteLine(subString.ToString() + ":" + subString.GetHashCode()); CodeTimer.Time(true, "new SubString().GetHashCode()", iterations, () => { new SubString(value, 1, 16).GetHashCode(); new SubString(value, 23, 3).GetHashCode(); new SubString(value, 1, 16).GetHashCode(); }); var ssComparer = new OrdinalIgnoreCaseSubStringComparer(); CodeTimer.Time(true, "new SubString().GetCaseInsensitiveHashCode()", iterations, () => { ssComparer.GetHashCode(new SubString(value, 1, 16)); ssComparer.GetHashCode(new SubString(value, 23, 3)); ssComparer.GetHashCode(new SubString(value, 1, 16)); }); CodeTimer.Time(true, "string.Substring().GetHashCode()", iterations, () => { string substring = value.Substring(1, 16); substring.GetHashCode(); substring = value.Substring(23, 3); substring.GetHashCode(); substring = value.Substring(1, 16); substring.GetHashCode(); }); StringComparer comparer = StringComparer.OrdinalIgnoreCase; CodeTimer.Time(true, "string.Substring().GetHashCode() insensitive", iterations, () => { string substring = value.Substring(1, 16); comparer.GetHashCode(substring); substring = value.Substring(23, 3); comparer.GetHashCode(substring); substring = value.Substring(1, 16); comparer.GetHashCode(substring); }); return(ran); }