示例#1
0
        public void MemoizerFactoryHashingTests_ConfigValueEquality()
        {
            MemoizerFactory <long, long> slow500Square_MemoizerFactory = new Func <long, long>(slow500Square).Memoize();

            MemoizerFactory <long, long> memoizerFactory1 = FIBONACCI.Memoize().KeepItemsCachedFor(13).Minutes.InstrumentWith(Console.WriteLine);
            MemoizerFactory <long, long> memoizerFactory2 = FIBONACCI.Memoize().KeepItemsCachedFor(13).Minutes.InstrumentWith(Console.WriteLine);
            MemoizerFactory <long, long> memoizerFactory3 = FIBONACCI.Memoize().KeepItemsCachedFor(13).Minutes;
            MemoizerFactory <long, long> memoizerFactory4 = FIBONACCI.Memoize().KeepItemsCachedFor(13).Seconds.InstrumentWith(Console.WriteLine);
            MemoizerFactory <long, long> memoizerFactory5 = slow500Square_MemoizerFactory.KeepItemsCachedFor(13).Minutes.InstrumentWith(Console.WriteLine);

            //Assert.That(MemoizerHelper.CreateMemoizerHash(memoizerFactory1), Is.EqualTo(MemoizerHelper.CreateMemoizerHash(memoizerFactory1)));
            //Assert.That(MemoizerHelper.CreateMemoizerHash(memoizerFactory1), Is.EqualTo(MemoizerHelper.CreateMemoizerHash(memoizerFactory2)));
            //// Logger action property not included in MemoizerFactory equality ...yet
            //Assert.That(MemoizerHelper.CreateMemoizerHash(memoizerFactory1), Is.EqualTo(MemoizerHelper.CreateMemoizerHash(memoizerFactory3)));
            //Assert.That(MemoizerHelper.CreateMemoizerHash(memoizerFactory1), Is.Not.EqualTo(MemoizerHelper.CreateMemoizerHash(memoizerFactory4)));
            //Assert.That(MemoizerHelper.CreateMemoizerHash(memoizerFactory1), Is.Not.EqualTo(MemoizerHelper.CreateMemoizerHash(memoizerFactory5)));

            // TODO: use reflection
            //Assert.That(memoizerFactory1.MemoizerConfiguration, Is.EqualTo(memoizerFactory1.MemoizerConfiguration));
            //Assert.That(memoizerFactory1.MemoizerConfiguration, Is.EqualTo(memoizerFactory2.MemoizerConfiguration));
            //// Logger action property not included in MemoizerFactory equality ...yet
            //Assert.That(memoizerFactory1.MemoizerConfiguration, Is.EqualTo(memoizerFactory3.MemoizerConfiguration));
            //Assert.That(memoizerFactory1.MemoizerConfiguration, Is.Not.EqualTo(memoizerFactory4.MemoizerConfiguration));
            //Assert.That(memoizerFactory1.MemoizerConfiguration, Is.Not.EqualTo(memoizerFactory5.MemoizerConfiguration));
        }
示例#2
0
        public void MemoizeOfT1T2T3T4T5()
        {
            Func <int, int, int, int, int, int> func = null;

            Assert.Throws <ArgumentNullException>(() => { func.Memoize(); });

            int count = 0;

            int firstExpected  = 1 + 2 + 3 + 4 + 5;
            int secondExpected = 2 + 4 + 6 + 8 + 10;

            func = (t1, t2, t3, t4, t5) => { count++; return(t1 + t2 + t3 + t4 + t5); };
            func = func.Memoize();

            Assert.AreEqual(firstExpected, func(1, 2, 3, 4, 5));
            Assert.AreEqual(firstExpected, func(1, 2, 3, 4, 5));
            Assert.AreEqual(firstExpected, func(1, 2, 3, 4, 5));


            Assert.AreEqual(secondExpected, func(2, 4, 6, 8, 10));
            Assert.AreEqual(secondExpected, func(2, 4, 6, 8, 10));
            Assert.AreEqual(secondExpected, func(2, 4, 6, 8, 10));


            Assert.AreEqual(2, count);
        }
示例#3
0
        public void MemoizeOfT1T2T3()
        {
            Func <int, int, int, int> func = null;

            Assert.Throws <ArgumentNullException>(() => { func.Memoize(); });

            int count = 0;

            int firstExpected  = 1 + 2 + 3;
            int secondExpected = 2 + 4 + 6;

            func = (t1, t2, t3) => { count++; return(t1 + t2 + t3); };
            func = func.Memoize();

            Assert.AreEqual(firstExpected, func(1, 2, 3));
            Assert.AreEqual(firstExpected, func(1, 2, 3));
            Assert.AreEqual(firstExpected, func(1, 2, 3));


            Assert.AreEqual(secondExpected, func(2, 4, 6));
            Assert.AreEqual(secondExpected, func(2, 4, 6));
            Assert.AreEqual(secondExpected, func(2, 4, 6));


            Assert.AreEqual(2, count);
        }
示例#4
0
        public void MemoizeOfT1()
        {
            Func <int, int> func = null;

            Assert.Throws <ArgumentNullException>(() => { func.Memoize(); });

            int count = 0;

            int firstExpected  = 1;
            int secondExpected = 2;

            func = (t1) => { count++; return(t1); };
            func = func.Memoize();

            Assert.AreEqual(firstExpected, func(1));
            Assert.AreEqual(firstExpected, func(1));
            Assert.AreEqual(firstExpected, func(1));


            Assert.AreEqual(secondExpected, func(2));
            Assert.AreEqual(secondExpected, func(2));
            Assert.AreEqual(secondExpected, func(2));


            Assert.AreEqual(2, count);
        }
示例#5
0
        public void MemoizeOfT1T2T3T4T5T6T7()
        {
            Func <int, int, int, int, int, int, int, int> func = null;

            Assert.Throws <ArgumentNullException>(() => { func.Memoize(); });

            int count = 0;

            int firstExpected  = 1 + 2 + 3 + 4 + 5 + 6 + 7;
            int secondExpected = 2 + 4 + 6 + 8 + 10 + 12 + 14;

            func = (t1, t2, t3, t4, t5, t6, t7) => { count++; return(t1 + t2 + t3 + t4 + t5 + t6 + t7); };
            func = func.Memoize();

            Assert.AreEqual(firstExpected, func(1, 2, 3, 4, 5, 6, 7));
            Assert.AreEqual(firstExpected, func(1, 2, 3, 4, 5, 6, 7));
            Assert.AreEqual(firstExpected, func(1, 2, 3, 4, 5, 6, 7));


            Assert.AreEqual(secondExpected, func(2, 4, 6, 8, 10, 12, 14));
            Assert.AreEqual(secondExpected, func(2, 4, 6, 8, 10, 12, 14));
            Assert.AreEqual(secondExpected, func(2, 4, 6, 8, 10, 12, 14));


            Assert.AreEqual(2, count);
        }
示例#6
0
 // Example 2 [expiration policy: keep items cached for 30 minutes]
 string ExpensiveFunctionWithExpiration(long someId)
 {
     //return myExpensiveFunction.Memoize().KeepItemsCachedFor(30).Minutes.GetMemoizer().InvokeWith(someId);
     //// Or
     ////return myExpensiveFunction.CacheFor(30).Minutes.GetMemoizer().InvokeWith(someId);
     return(myExpensiveFunction.Memoize().KeepItemsCachedFor(1).Seconds.GetMemoizer().InvokeWith(someId));
     // Or
     //return myExpensiveFunction.CacheFor(1).Seconds.GetMemoizer().InvokeWith(someId);
 }
示例#7
0
 /// <summary>
 /// Function that simulates the square of one of the two parameters (at random).
 /// Uses lazy evaluation. Since C# does not implement lazy parameters, it is
 /// achieved passing two functions as parameters. Whenever the value of the
 /// paramters are needed, the functions are called.
 /// If the parameters are not used, the functions are not called.
 /// The functions are memoized.
 /// </summary>
 /// <returns>The square of one of the parameters (at random)</returns>
 internal static double LazySquare(Func <int> param1, Func <int> param2)
 {
     if (new Random().Next() % 2 == 0)
     {
         return(param1.Memoize() * param1.Memoize());
     }
     else
     {
         return(param2.Memoize() * param2.Memoize());
     }
 }
示例#8
0
        public void UnMemoize()
        {
            IMemoizer <long, string> standaloneMemoizer = myExpensiveFunction.CacheFor(30).Minutes.InstrumentWith(Console.WriteLine).CreateMemoizer();

            MemoizerFactory <long, string> sharedMemoizerConfig1 = myExpensiveFunction.CacheFor(30).Minutes.InstrumentWith(Console.WriteLine);
            MemoizerFactory <long, string> sharedMemoizerConfig2 = myExpensiveFunction.Memoize().InstrumentWith(Console.WriteLine);
            MemoizerFactory <long, string> sharedMemoizerConfig3 = typicalDatabaseInvocation_DelegatedFunc3.Memoize().InstrumentWith(Console.WriteLine);

            // Nope - this does not fly - cannot close mutable structures in a Func ...#help why?
            //Func<long, string> standaloneMemoizerInvocation = standaloneMemoizer.InvokeWith;
            //Func<long, string> sharedMemoizer1Invocation = sharedMemoizerConfig1.GetMemoizer().InvokeWith;
            //Func<long, string> sharedMemoizer2Invocation = sharedMemoizerConfig2.GetMemoizer().InvokeWith;
            //Func<long, string> sharedMemoizer3Invocation = sharedMemoizerConfig3.GetMemoizer().InvokeWith;

            // The standalone memoizer instance is not cached yet
            AssertThat(standaloneMemoizer.InvokeWith, 1989L, Is.GreaterThanOrEqualTo(DATABASE_RESPONSE_LATENCY_IN_MILLIS));

            // ...now it is
            AssertThat(standaloneMemoizer.InvokeWith, 1989L, Is.LessThan(10));

            // The memoizer^2 registry instances are either cached, or not...
            sharedMemoizerConfig1.GetMemoizer().InvokeWith(1989L);
            sharedMemoizerConfig1.GetMemoizer().InvokeWith(2089L);
            sharedMemoizerConfig2.GetMemoizer().InvokeWith(1989L);
            sharedMemoizerConfig3.GetMemoizer().InvokeWith(1989L);

            // ...now they are
            AssertThat(sharedMemoizerConfig1.GetMemoizer().InvokeWith, 1989L, Is.LessThan(10));
            AssertThat(sharedMemoizerConfig1.GetMemoizer().InvokeWith, 2089L, Is.LessThan(10));
            AssertThat(sharedMemoizerConfig2.GetMemoizer().InvokeWith, 1989L, Is.LessThan(10));
            AssertThat(sharedMemoizerConfig3.GetMemoizer().InvokeWith, 1989L, Is.LessThan(10));

            // Remove all shared memoizers having function 'myExpensiveFunction'
            myExpensiveFunction.UnMemoize();

            // Standalone memoizer instance is not affected
            AssertThat(standaloneMemoizer.InvokeWith, 1989L, Is.LessThan(10));

            AssertThat(sharedMemoizerConfig1.GetMemoizer().InvokeWith, 1989L, Is.GreaterThanOrEqualTo(DATABASE_RESPONSE_LATENCY_IN_MILLIS));
            AssertThat(sharedMemoizerConfig1.GetMemoizer().InvokeWith, 1989L, Is.LessThan(10));

            // ...for all arguments
            AssertThat(sharedMemoizerConfig1.GetMemoizer().InvokeWith, 2089L, Is.GreaterThanOrEqualTo(DATABASE_RESPONSE_LATENCY_IN_MILLIS));
            AssertThat(sharedMemoizerConfig1.GetMemoizer().InvokeWith, 2089L, Is.LessThan(10));

            // Second registry memoizer is using the same Func, so it is also cleared
            AssertThat(sharedMemoizerConfig2.GetMemoizer().InvokeWith, 1989L, Is.GreaterThanOrEqualTo(DATABASE_RESPONSE_LATENCY_IN_MILLIS));
            AssertThat(sharedMemoizerConfig2.GetMemoizer().InvokeWith, 1989L, Is.LessThan(10));

            // Third registry memoizer is a different Func, so it is not affected
            AssertThat(sharedMemoizerConfig3.GetMemoizer().InvokeWith, 1989L, Is.LessThan(10));
        }
示例#9
0
        static void Main()
        {
            Console.SetWindowSize(100, 58);

            Func <ulong, ulong> fib = null;

            fib = x => x > 1 ? fib(x - 1) + fib(x - 2) : x;
            fib = fib.Memoize();

            Func <ulong, decimal> fibConstant = null;

            fibConstant = x => (x == 1) ? 1 / ((decimal)fib(x)) : 1 / ((decimal)fib(x)) + fibConstant(x - 1);

            fibConstant = fibConstant.Memoize();

            Console.WriteLine("\n{0}\t{1}\t{2}\t{3}\n", "Count", "Fibonacci".PadRight(24), "1/Fibonacci".PadRight(24), "Fibonacci Constant".PadRight(24));

            for (ulong i = 1; i <= 93; ++i)
            {
                Console.WriteLine("{0:D5}\t{1:D24}\t{2:F24}\t{3:F24}", i, fib(i), (1 / (decimal)fib(i)), fibConstant(i));
            }

            // Задержка.
            Console.ReadKey();
        }
示例#10
0
        public static Func <T1, T2, T3, T4, T5, R> Memoize <T1, T2, T3, T4, T5, R>(this Func <T1, T2, T3, T4, T5, R> func)
        {
            Func <Tuple <T1, T2, T3, T4, T5>, R> temp = (t) => func(t.Item1, t.Item2, t.Item3, t.Item4, t.Item5);

            temp = temp.Memoize();
            return((t1, t2, t3, t4, t5) => temp(Tuple.Create(t1, t2, t3, t4, t5)));
        }
示例#11
0
        public static Func <T1, T2, T3, R> Memoize <T1, T2, T3, R>(this Func <T1, T2, T3, R> func)
        {
            Func <Tuple <T1, T2, T3>, R> temp = (t) => func(t.Item1, t.Item2, t.Item3);

            temp = temp.Memoize();
            return((t1, t2, t3) => temp(Tuple.Create(t1, t2, t3)));
        }
示例#12
0
 public static Func <T, U, V> Memoize <T, U, V>(
     this Func <T, U, V> func,
     IEqualityComparer <T> comparerT,
     IEqualityComparer <U> comparerU)
 {
     return(func.Memoize(AsTupleComparer(comparerT, comparerU)));
 }
示例#13
0
        public static long GetNumberOfWays(int staircaseSize)
        {
            Func <int, long> climb = null;

            climb = (n) =>
            {
                if (n == 0)
                {
                    return(0);
                }

                if (n == 1)
                {
                    return(1);
                }

                if (n == 2)
                {
                    return(2);
                }

                if (n == 3)
                {
                    return(4);
                }

                return(climb(n - 1) + climb(n - 2) + climb(n - 3));
            };

            climb = climb.Memoize();

            return(climb(staircaseSize));
        }
示例#14
0
        public void Memoize(string dummyResult)
        {
            var           counter = 0;
            Func <string> dummy   = () =>
            {
                counter++;

                return(dummyResult);
            };

            var result1 = dummy.Memoize("getData1");
            var result2 = dummy.Memoize("getData1");
            var result3 = dummy.Memoize("getData1");

            Assert.Equal(1, counter);
        }
示例#15
0
            public static long GetFiboOf(long number)
            {
                Func <long, long> fibo = null;

                fibo = n =>
                {
                    if (n == 0)
                    {
                        return(0);
                    }

                    if (n == 1)
                    {
                        return(1);
                    }

                    return
                        // ReSharper disable once PossibleNullReferenceException
                        // ReSharper disable once AccessToModifiedClosure
                        (fibo(n - 1)
                         +
                         // ReSharper disable once PossibleNullReferenceException
                         // ReSharper disable once AccessToModifiedClosure
                         fibo(n - 2));
                };
                fibo = fibo.Memoize();
                return(fibo(number));
            }
示例#16
0
 public TableHeap(MetadataHeaps heaps, byte[] buffer) : base(buffer, 0x08)
 {
     MoveTo(START_POSITION);
     _heaps        = heaps;
     _tables       = GetMetadataTables();
     _isLargeToken = Func.Memoize <CodedTokenType, bool>(type => CodedTokenSchema.IsLargeToken(type, this));
 }
示例#17
0
    public void LocalFunction_ShouldBeMemoized()
    {
        var numberOfCalls = 0;

        Func <int, int> fibonacci = null;

        fibonacci = n1 =>
        {
            numberOfCalls++;

            if (n1 <= 2)
            {
                return(1);
            }

            return(fibonacci(n1 - 1) + fibonacci(n1 - 2));
        };

        fibonacci = fibonacci.Memoize();

        var result = fibonacci(3);

        result.Should().Be(2);
        numberOfCalls.Should().Be(3);


        var secondResult = fibonacci(3);

        secondResult.Should().Be(2);
        numberOfCalls.Should().Be(3);
    }
示例#18
0
        public void MemoizeShouldReturnFunction()
        {
            Func <int, int> func   = i => i;
            var             result = func.Memoize();

            result.Should().NotBeNull();
        }
示例#19
0
        public Tribonacci()
        {
            fib = n => n > 2 ? fib(n - 1) + fib(n - 2) + fib(n - 3) : 1;

            fibMemoize = n => n > 2 ? fibMemoize(n - 1) + fibMemoize(n - 2) + fibMemoize(n - 3) : 1;
            fibMemoize = fibMemoize.Memoize();
        }
示例#20
0
        public void FuncMemoizedWithExpirableMemoizerShouldBeCalledFewerTimesThanCallingThreadCount()
        {
            // Arrange
            var callCount     = 0;
            var callCountLock = new object();

            Func <int, int> getValueSquared = i =>
            {
                lock (callCountLock)
                {
                    callCount++;
                }

                return(i * i);
            };

            var memoized = getValueSquared.Memoize(true);

            // Act
            Parallel.For(0, InvocationCount, Assert2SquaredIs4(memoized));

            // Assert
            Console.WriteLine(callCount);
            callCount.Should().BeLessThan(InvocationCount);
        }
示例#21
0
        // A9: Number of classroom teachers by teaching level of education, employment status, type of institution and sex
        void sheetA9(Excel.Application excelApp, SqlConnection sqlConn, string year, string country)
        {
            //Constant references for columns and rows
            const int FEMALE_OFFSET = 1;     //row offset
            const int PUBLIC        = 14;
            const int PRIVATE       = 17;

            Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.Worksheets["A9"];
            workSheet.Activate();
            Excel.Range usedRange = workSheet.UsedRange;

            Func <string, int> getCol = null;

            getCol = n => usedRange.Find(n).Column;
            getCol.Memoize();

            SqlCommand cmd = new SqlCommand(
                @"select ISCED, SCHOOLTYPE, GENDER, sum(COUNT) as COUNT 
                    from #TeacherBaseTable
                    group by ISCED, SCHOOLTYPE, GENDER",
                sqlConn);


            using (SqlDataReader rdr = cmd.ExecuteReader())
            {
                while (rdr.Read())
                {
                    string isced      = rdr.GetString(0);
                    string schoolType = rdr.GetString(1);
                    string gender     = rdr.GetString(2);
                    int    count      = rdr.GetInt32(3);
                    Console.WriteLine(String.Format("{0}, {1}, {2}, {3}", isced, gender, schoolType, count.ToString()));

                    int rowOffset = gender == "M" ? 0 : FEMALE_OFFSET;
                    int row       = schoolType == "PUBLIC" ? PUBLIC : PRIVATE + rowOffset;

                    List <string> columns = new List <string>();

                    if (isced == "ISCED 24" || isced == "ISCED 34")
                    {
                        columns.Add("ISCED 24+34");
                        columns.Add(isced.Substring(0, 7));
                    }
                    else if (isced == "ISCED 25" || isced == "ISCED 35")
                    {
                        columns.Add("ISCED 25+35");
                        columns.Add(isced.Substring(0, 7));
                    }
                    else
                    {
                        columns.Add(isced);
                    }
                    foreach (string column in columns)
                    {
                        workSheet.Cells[row, getCol(column)] = workSheet.get_Range(helpers.GetCellAddress(getCol(column), row)).Value2 + count;
                    }
                }
            }
        }
示例#22
0
        /// <summary>
        /// Creates a new instance of the <see cref="BaseNamespaceManager" /> class.
        /// </summary>
        /// <param name="manager">XmlNamespaceManager to use.</param>
        public BaseNamespaceManager(XmlNamespaceManager manager)
        {
            this.manager = manager;

            Func <string, string> f = this.QualifyNamespace;

            this.nsQual = f.Memoize();
        }
示例#23
0
 public MetadataReader(MetadataHeaps heaps, MetadataToken entryPoint)
 {
     _heaps             = heaps;
     _entryPoint        = entryPoint;
     _resolveBlob       = Func.Memoize <uint, ByteBuffer>(_heaps.Blobs.ReadBlob);
     _resolveGuid       = Func.Memoize <uint, Guid>(_heaps.Guids.ReadGuid);
     _resolveString     = Func.Memoize <uint, string>(_heaps.Strings.ReadString);
     _resolveUserString = Func.Memoize <uint, string>(_heaps.UserStrings.ReadString);
 }
示例#24
0
        //constructors

        //static methods
        static long count(IEnumerable <int> source, int sum)
        {
            Func <int, int, long> func = null;

            func = (skip, remaining) => source.Skip(skip).Select((x, i) => (x > remaining) ? 0L : func(skip + i, remaining - x)).Sum();
            func = func.Memoize();
            func = func.When((skip, remaining) => remaining == 0, (maxUnit, remaining) => 1L);
            return(func(0, sum));
        }
示例#25
0
        public static Func <TIn, TOut> Create <TIn, T1, TOut>(
            Func <TIn, T1> argSelector,
            Func <T1, TOut> resultSelector)
        {
            var memoizedResultSelector = resultSelector.Memoize();

            return(Create <TIn, TOut>(
                       input => memoizedResultSelector.Invoke(
                           argSelector.Invoke(input))));
        }
        public void Test_Map(int[] keys, int[] values, [PexAssumeNotNull] Func <int, int, int> func)
        {
            var dict = CreateDictionary(keys, values);

            PexAssume.AreNotEqual(0, keys.Length);
            func = func.Memoize();
            var dict1 = dict.Map(func);

            PexAssert.AreEqual(func(keys[0], values[0]), dict1[keys[0]]);
        }
示例#27
0
        public void Memoize_IsTransparent()
        {
            int counter          = 0;
            Func <string, int> f = x => counter++;

            var g = f.Memoize();

            Assert.AreEqual(g("foo"), 0);
            Assert.AreEqual(g("bar"), 1);
        }
示例#28
0
        // [bbeckman: this one is creepy.]
        public Maybe <U> Extend <U>(Func <Maybe <T>, Maybe <U> > func)
        {
            Contract.Requires(null != func, "func");

            var self = this;

            Func <Maybe <U> .MaybeResult> boundComputation =
                () => Maybe <U> .ComputeResult(func(self));

            return(new Maybe <U>(boundComputation.Memoize()));
        }
示例#29
0
 private MetadataBuilder(AssemblyDefinition assemblyDef)
 {
     _assemblyDef     = assemblyDef;
     _heaps           = new MetadataHeaps();
     _ilCode          = new ILCodeWriter(this);
     _writeBlob       = Func.Memoize <ByteBuffer, uint>(_heaps.Blobs.WriteBlob);
     _writeGuid       = Func.Memoize <Guid, uint>(_heaps.Guids.WriteGuid);
     _writeString     = Func.Memoize <string, uint>(_heaps.Strings.WriteString, StringComparer.Ordinal);
     _writeUserString = Func.Memoize <string, uint>(_heaps.UserStrings.WriteString, StringComparer.Ordinal);
     _resolveToken    = Func.Memoize <IMetadataEntity, MetadataToken>(entity => MetadataTokenResolver.ResolveToken(entity, this));
 }
示例#30
0
        static void FastFib() // Версия с мемоизацией результатов и меньшей нагрузкой на стек
        {
            Func <int, int> fib = null;

            fib = x => x > 1 ? fib(x - 1) + fib(x - 2) : x;
            fib = fib.Memoize();
            for (int i = 30; i < 40; i++)
            {
                Console.WriteLine(fib(i));
            }
        }
 static CharRangeAST()
 {
     Make = (minCharacter, maxCharacter, foldCaseCompare) =>
     {
         if (minCharacter > maxCharacter)
             return NotTestAST.Make(AnyCharAST.Instance);
         else if (minCharacter == maxCharacter)
             return OneCharAST.Make(minCharacter, foldCaseCompare);
         else
             return new CharRangeAST(minCharacter, maxCharacter, foldCaseCompare);
     };
     Make = Make.Memoize();
 }
示例#32
0
        public bool MemzTest(Func<int, int, int> f, int target1, int target2)
        {
            Stopwatch stopwatch = new Stopwatch ();

            // time it raw
            stopwatch.Start ();
            var rawR = f (target1, target2);
            stopwatch.Stop ();
            var rawT = stopwatch.ElapsedTicks;
            stopwatch.Reset ();

            // memoized function
            f = f.Memoize ();

            // time it memoized:

            // first run : same speed
            stopwatch.Start ();
            f (target1, target2);
            stopwatch.Stop ();
            var memT1 = stopwatch.ElapsedTicks;
            stopwatch.Reset ();

            // second run: faster
            stopwatch.Start ();
            var memR = f (target1, target2);
            stopwatch.Stop ();
            var memT2 = stopwatch.ElapsedTicks;

            // Accurate?
            Assert.AreEqual (rawR, memR);

            // Mem2 is faster than mem1?
            Assert.GreaterOrEqual(memT1, memT2);

            // Mem2 is faster than raw?
            //Console.WriteLine("{0}\t{1}\t{2}", rawT, memT1, memT2);
            return rawT > memT2 ? true : false;
        }
 static AndTestAST()
 {
     Make = (left, right) => Build(left, right);
     Make = Make.Memoize();
 }
 static OneCharAST()
 {
     Make = (character, foldCaseCompare) => new OneCharAST(character, foldCaseCompare);
     Make = Make.Memoize();
 }
 static NotTestAST()
 {
     Make = argument => Build(argument);
     Make = Make.Memoize();
 }
 /// <summary>Initializes and compiles a regular expression, with options that modify the pattern.</summary>
 /// <param name="regexRep">The pattern to be compiled.</param>
 /// <param name="opts">The options desired.</param>
 /// <exception cref="ArgumentException"><paramref name="regexRep"/> is an ill-formed pattern.</exception>
 internal NFABuilder(string regexRep, RegexOptions opts)
 {
     pending = new Queue<ASTTransition>();
     visited = new Dictionary<RegexAST, int>();
     instructIndex = ast =>
     {
         Instructions.Add(ast.ToInstruction(this));
         return Instructions.Count - 1;
     };
     instructIndex = instructIndex.Memoize();
     ParseInfo = new AnnotationVisitor(regexRep);
     SyntaxTree = Parser.Parse(regexRep, opts);
     SyntaxTree.Annotate(ParseInfo);
     IgnoreCase = (opts & RegexOptions.IgnoreCase) != 0;
 }