Ejemplo n.º 1
0
        public static void DoBenchmark()
        {
            const int Iterations = 10000000;

            // Measure the time it takes to instantiate ten versions of
            // IReadOnlyList<T>. GoInterface is not able to create generic wrappers,
            // so every time you wrap the same generic type with a different type
            // parameter, GoInterface produces a completely separate wrapper. This
            // is not good for performance, but at least it makes it easy for our
            // benchmark to pick 10 "different" classes to create wrappers of.
            //
            // It is possible to wrap List<byte> not only as IReadOnlyList<byte>
            // but also as any larger integer type, such as IReadOnlyList<int>.
            // However, the wrapping of the GetEnumerator() methods doesn't work.
            // List<byte>.GetEnumerator() returns IEnumerator<byte>, but
            // IReadOnlyList<int>.GetEnumerator() returns IEnumerator<int>. There is
            // no implicit conversion from IEnumerator<byte> to IEnumerator<int>,
            // so GoInterface fails to wrap it. However, by using ForceFrom we get
            // around this limitation, which still allows us to use the indexer and
            // Count properties. If you call GetEnumerator(), though, you get a
            // MissingMethodException.
            //
            // Note that if you run this part of the benchmark twice without
            // exiting the program, the second time around it should take zero
            // milliseconds. And the benchmark generally runs more slowly right
            // after you reboot your computer.
            SimpleTimer timer  = new SimpleTimer();
            var         dummy0 = GoInterface <IListSource <byte> > .ForceFrom(new List <byte>());

            int firstOne = timer.Millisec;
            var dummy1   = GoInterface <IListSource <short> > .ForceFrom(new List <byte>());

            var dummy2 = GoInterface <IListSource <ushort> > .ForceFrom(new List <byte>());

            var dummy3 = GoInterface <IListSource <int> > .ForceFrom(new List <byte>());

            var dummy4 = GoInterface <IListSource <uint> > .ForceFrom(new List <byte>());

            var dummy5 = GoInterface <IListSource <long> > .ForceFrom(new List <byte>());

            var dummy6 = GoInterface <IListSource <ulong> > .ForceFrom(new List <byte>());

            var dummy7 = GoInterface <IListSource <float> > .ForceFrom(new List <byte>());

            var dummy8 = GoInterface <IListSource <double> > .ForceFrom(new List <byte>());

            var dummy9 = GoInterface <IListSource <object> > .ForceFrom(new List <byte>());

            int firstTen = timer.Millisec;

            Console.WriteLine("First ten interfaces were wrapped in {0}ms ({1}ms for the first)", firstTen, firstOne);

            // Second test: measure how long it takes to wrap the same List<int>
            // many times, using either GoInterface class.
            var list = new List <int>();

            list.Add(0);
            list.Add(1);
            list.Add(2);
            list.Add(3);
            IList <int>       ilist;
            IListSource <int> rolist;

            GoInterface <IListSource <int> > .From(list);         // ignore first call

            timer.Restart();
            int i = 0;

            do
            {
                ilist = list;                 // normal interface assignment is pretty much a no-op
            } while (++i < Iterations);
            int wrapTest0 = timer.Restart();

            i = 0;
            do
            {
                rolist = GoInterface <IListSource <int> > .From(list);
            } while (++i < Iterations);
            int wrapTest1 = timer.Restart();

            i = 0;
            do
            {
                rolist = GoInterface <IListSource <int>, List <int> > .From(list);
            } while (++i < Iterations);
            int wrapTest2 = timer.Restart();

            Console.WriteLine("Wrapper creation speed ({0} times):", Iterations);
            Console.WriteLine("- {0} ms for normal .NET interfaces (no-op)", wrapTest0);
            Console.WriteLine("- {0} ms for GoInterface<IReadOnlyList<int>>.From()", wrapTest1);
            Console.WriteLine("- {0} ms for GoInterface<IReadOnlyList<int>,List<int>>.From()", wrapTest2);

            int total0 = 0, total1 = 0, total2 = 0;

            timer.Restart();
            for (i = 0; i < Iterations; i++)
            {
                total0 += list[i & 3];
            }
            int callTestDirectCall = timer.Restart();

            for (i = 0; i < Iterations; i++)
            {
                total1 += ilist[i & 3];
            }
            int callTestNormalInterface = timer.Restart();

            for (i = 0; i < Iterations; i++)
            {
                total2 += rolist[i & 3];
            }
            int callTestGoInterface = timer.Restart();

            Debug.Assert(total0 == total1 && total1 == total2);

            Console.WriteLine("Indexer call speed ({0} times):", Iterations);
            Console.WriteLine("- {0} ms for direct calls (not through an interface)", callTestDirectCall);
            Console.WriteLine("- {0} ms through IList<int>", callTestNormalInterface);
            Console.WriteLine("- {0} ms through IReadOnlyList<int>", callTestGoInterface);
        }
Ejemplo n.º 2
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(GoInterface obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
Ejemplo n.º 3
0
 public static ReverseView <T> From(IList <T> list)
 {
     return(GoInterface <ReverseView <T>, IList <T> > .From(list));
 }