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 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);
        }