示例#1
0
        public void GenericMarshalingOverhead_Int32ArrayArrayArray()
        {
#if __ANDROID__
            const int C = 100;
#else   // __ANDROID__
            const int C = 100;
#endif  // __ANDROID__

            var total = Stopwatch.StartNew();

            var value = new int[][][] {
                new int[][] {
                    new int[] { 111, 112, 113 },
                    new int[] { 121, 122, 123 },
                },
                new int[][] {
                    new int[] { 211, 212, 213 },
                    new int[] { 221, 222, 223 },
                },
            };

            using (var t = new JavaTiming()) {
                var n = Stopwatch.StartNew();
                for (int i = 0; i < C; ++i)
                {
                    t.VirtualIntMethod1Args(value);
                }
                n.Stop();

                var m = Stopwatch.StartNew();
                for (int i = 0; i < C; ++i)
                {
                    t.Timing_VirtualIntMethod_Marshal1Args(value);
                }
                m.Stop();

                var g = Stopwatch.StartNew();
                for (int i = 0; i < C; ++i)
                {
                    t.Timing_VirtualIntMethod_GenericMarshal1Args(value);
                }
                g.Stop();

                Console.WriteLine("Generic Marshaling Overhead: ([[[I)I");
                Console.WriteLine("\t Native Marshaling: {0}", n.Elapsed);
                Console.WriteLine("\tPartial Marshaling: {0}", m.Elapsed);
                Console.WriteLine("\tGeneric Marshaling: {0}", g.Elapsed);
            }

            total.Stop();
            Console.WriteLine("## {0} Timing: {1}", nameof(GenericMarshalingOverhead_Int32ArrayArrayArray), total.Elapsed);
        }
示例#2
0
        public void GenericMarshalingOverhead_Int32()
        {
            const int C = 10000;

            var total = Stopwatch.StartNew();

            using (var t = new JavaTiming()) {
                var n = Stopwatch.StartNew();
                for (int i = 0; i < C; ++i)
                {
                    t.VirtualIntMethod1Args(i);
                }
                n.Stop();

                var m = Stopwatch.StartNew();
                for (int i = 0; i < C; ++i)
                {
                    t.Timing_VirtualIntMethod_Marshal1Args(i);
                }
                m.Stop();

                var g = Stopwatch.StartNew();
                for (int i = 0; i < C; ++i)
                {
                    t.Timing_VirtualIntMethod_GenericMarshal1Args(i);
                }
                g.Stop();

                Console.WriteLine("Generic Marshaling Overhead: (I)I");
                Console.WriteLine("\t Native Marshaling: {0}", n.Elapsed);
                Console.WriteLine("\tPartial Marshaling: {0}", m.Elapsed);
                Console.WriteLine("\tGeneric Marshaling: {0}", g.Elapsed);
            }

            total.Stop();
            Console.WriteLine("## {0} Timing: {1}", nameof(GenericMarshalingOverhead_Int32), total.Elapsed);
        }
示例#3
0
        public unsafe void MethodInvocationTiming()
        {
            FooMethods pinvoke_methods;

            foo_get_methods(out pinvoke_methods);

            var p_instance_void = (DV)Marshal.GetDelegateForFunctionPointer(pinvoke_methods.instance_void, typeof(DV));
            var p_instance_int  = (DI)Marshal.GetDelegateForFunctionPointer(pinvoke_methods.instance_int, typeof(DI));
            var p_instance_ptr  = (DP)Marshal.GetDelegateForFunctionPointer(pinvoke_methods.instance_ptr, typeof(DP));

            var p_void_1a = (DV1A)Marshal.GetDelegateForFunctionPointer(pinvoke_methods.void_1_args, typeof(DV1A));
            var p_void_2a = (DV2A)Marshal.GetDelegateForFunctionPointer(pinvoke_methods.void_2_args, typeof(DV2A));
            var p_void_3a = (DV3A)Marshal.GetDelegateForFunctionPointer(pinvoke_methods.void_3_args, typeof(DV3A));

            var p_void_1ai = (DV1AI)Marshal.GetDelegateForFunctionPointer(pinvoke_methods.void_1_iargs, typeof(DV1AI));
            var p_void_2ai = (DV2AI)Marshal.GetDelegateForFunctionPointer(pinvoke_methods.void_2_iargs, typeof(DV2AI));
            var p_void_3ai = (DV3AI)Marshal.GetDelegateForFunctionPointer(pinvoke_methods.void_3_iargs, typeof(DV3AI));

            var Object_class = new JniType("java/lang/Object");
            var Object_init  = Object_class.GetConstructor("()V");

            var transfer = JniObjectReferenceOptions.CopyAndDispose;

            var jobj1 = CreateJavaObject(Object_class.NewObject(Object_init, null), transfer);
            var jobj2 = CreateJavaObject(Object_class.NewObject(Object_init, null), transfer);
            var jobj3 = CreateJavaObject(Object_class.NewObject(Object_init, null), transfer);

            var obj1 = new SomeClass();
            var obj2 = new SomeClass();
            var obj3 = new SomeClass();

            var j           = new JavaTiming();
            var m           = new ManagedTiming();
            var comparisons = new[] {
                new {
                    Name    = "static void",
                    Jni     = A(() => JavaTiming.StaticVoidMethod()),
                    Managed = A(() => ManagedTiming.StaticVoidMethod()),
                    Pinvoke = A(() => foo_void_timing()),
                },
                new {
                    Name    = "static int",
                    Jni     = A(() => JavaTiming.StaticIntMethod()),
                    Managed = A(() => ManagedTiming.StaticIntMethod()),
                    Pinvoke = A(() => foo_int_timing()),
                },
                new {
                    Name    = "static object",
                    Jni     = A(() => JavaTiming.StaticObjectMethod()),
                    Managed = A(() => ManagedTiming.StaticObjectMethod()),
                    Pinvoke = A(() => foo_ptr_timing()),
                },
                new {
                    Name    = "virtual void",
                    Jni     = A(() => j.VirtualVoidMethod()),
                    Managed = A(() => m.VirtualVoidMethod()),
                    Pinvoke = A(() => p_instance_void()),
                },
                new {
                    Name    = "virtual int",
                    Jni     = A(() => j.VirtualIntMethod()),
                    Managed = A(() => m.VirtualIntMethod()),
                    Pinvoke = A(() => p_instance_int()),
                },
                new {
                    Name    = "virtual object",
                    Jni     = A(() => j.VirtualObjectMethod()),
                    Managed = A(() => m.VirtualObjectMethod()),
                    Pinvoke = A(() => p_instance_ptr()),
                },
                new {
                    Name    = "final void",
                    Jni     = A(() => j.FinalVoidMethod()),
                    Managed = A(() => m.FinalVoidMethod()),
                    Pinvoke = A(null),
                },
                new {
                    Name    = "final int",
                    Jni     = A(() => j.FinalIntMethod()),
                    Managed = A(() => m.FinalIntMethod()),
                    Pinvoke = A(null),
                },
                new {
                    Name    = "final object",
                    Jni     = A(() => j.FinalObjectMethod()),
                    Managed = A(() => m.FinalObjectMethod()),
                    Pinvoke = A(null),
                },
                new {
                    Name    = "static void o1",
                    Jni     = A(() => JavaTiming.StaticVoidMethod1Args(jobj1)),
                    Managed = A(() => ManagedTiming.StaticVoidMethod1Args(obj1)),
                    Pinvoke = A(() => {
                        // We include timing of the GCHandle manipulation since
                        // a JNI invocation has to do similar work, and pinning
                        // is usually always needed for P/Invokes.
                        GCHandle h1  = GCHandle.Alloc(obj1, GCHandleType.Pinned);
                        IntPtr addr1 = h1.AddrOfPinnedObject();

                        p_void_1a(addr1);

                        h1.Free();
                    }),
                },
                new {
                    Name    = "static void o2",
                    Jni     = A(() => JavaTiming.StaticVoidMethod2Args(jobj1, jobj2)),
                    Managed = A(() => ManagedTiming.StaticVoidMethod2Args(obj1, obj2)),
                    Pinvoke = A(() => {
                        GCHandle h1  = GCHandle.Alloc(obj1, GCHandleType.Pinned),
                        h2           = GCHandle.Alloc(obj2, GCHandleType.Pinned);
                        IntPtr addr1 = h1.AddrOfPinnedObject(),
                        addr2        = h2.AddrOfPinnedObject();

                        p_void_2a(addr1, addr2);

                        h1.Free();
                        h2.Free();
                    }),
                },
                new {
                    Name    = "static void o3",
                    Jni     = A(() => JavaTiming.StaticVoidMethod3Args(jobj1, jobj2, jobj3)),
                    Managed = A(() => ManagedTiming.StaticVoidMethod3Args(obj1, obj2, obj3)),
                    Pinvoke = A(() => {
                        GCHandle h1  = GCHandle.Alloc(obj1, GCHandleType.Pinned),
                        h2           = GCHandle.Alloc(obj2, GCHandleType.Pinned),
                        h3           = GCHandle.Alloc(obj3, GCHandleType.Pinned);
                        IntPtr addr1 = h1.AddrOfPinnedObject(),
                        addr2        = h2.AddrOfPinnedObject(),
                        addr3        = h3.AddrOfPinnedObject();

                        p_void_3a(addr1, addr2, addr3);

                        h1.Free();
                        h2.Free();
                        h3.Free();
                    }),
                },
                new {
                    Name    = "static void i1",
                    Jni     = A(() => JavaTiming.StaticVoidMethod1IArgs(42)),
                    Managed = A(() => ManagedTiming.StaticVoidMethod1IArgs(42)),
                    Pinvoke = A(() => p_void_1ai(42)),
                },
                new {
                    Name    = "static void i2",
                    Jni     = A(() => JavaTiming.StaticVoidMethod2IArgs(42, 42)),
                    Managed = A(() => ManagedTiming.StaticVoidMethod2IArgs(42, 42)),
                    Pinvoke = A(() => p_void_2ai(42, 42)),
                },
                new {
                    Name    = "static void i3",
                    Jni     = A(() => JavaTiming.StaticVoidMethod3IArgs(42, 42, 42)),
                    Managed = A(() => ManagedTiming.StaticVoidMethod3IArgs(42, 42, 42)),
                    Pinvoke = A(() => p_void_3ai(42, 42, 42)),
                },
            };

#if __ANDROID__
            const int count = 1000;
#else   // __ANDROID__
            const int count = 100000;
#endif  // __ANDROID__

            var total = Stopwatch.StartNew();

            foo_init(JniEnvironment.EnvironmentPointer);

            var jniTimes = new long [comparisons.Length];
            foo_get_native_jni_timings(JniEnvironment.EnvironmentPointer, count, JavaTiming.TypeRef.PeerReference.Handle, j.PeerReference.Handle, jniTimes);

            int jniTimeIndex = 0;
            foreach (var c in comparisons)
            {
                var jw = System.Diagnostics.Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    c.Jni();
                }
                jw.Stop();

                var mw = System.Diagnostics.Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    c.Managed();
                }
                mw.Stop();

                System.Diagnostics.Stopwatch pw = null;
                if (c.Pinvoke != null)
                {
                    pw = System.Diagnostics.Stopwatch.StartNew();
                    for (int i = 0; i < count; ++i)
                    {
                        c.Pinvoke();
                    }
                    pw.Stop();
                }

                string message = string.Format("Method Invoke: {0}: JNI is {1}x managed",
                                               c.Name, System.Math.Round(jw.Elapsed.TotalMilliseconds / mw.Elapsed.TotalMilliseconds));
                Console.WriteLine(message);

                var ct = TimeSpan.FromMilliseconds(jniTimes [jniTimeIndex++]);
                Console.WriteLine("\t  C/JNI: {0} ms               | average: {1} ms",
                                  FormatFraction(ct.TotalMilliseconds, 10, 5),
                                  FormatFraction(ct.TotalMilliseconds / count, 12, 5));
                Console.WriteLine("\t    JNI: {0} ms; {1,3}x C/JNI   | average: {2} ms",
                                  FormatFraction(jw.Elapsed.TotalMilliseconds, 10, 5),
                                  ToString(jw.Elapsed, ct),
                                  FormatFraction(jw.Elapsed.TotalMilliseconds / count, 12, 5));
                Console.WriteLine("\tManaged: {0} ms               | average: {1} ms",
                                  FormatFraction(mw.Elapsed.TotalMilliseconds, 10, 5),
                                  FormatFraction(mw.Elapsed.TotalMilliseconds / count, 12, 5));
                if (pw != null)
                {
                    Console.WriteLine("\tPinvoke: {0} ms; {1,3}x managed | average: {2} ms",
                                      FormatFraction(pw.Elapsed.TotalMilliseconds, 10, 5),
                                      ToString(pw.Elapsed, mw.Elapsed),
                                      FormatFraction(pw.Elapsed.TotalMilliseconds / count, 12, 5));
                }
            }

            total.Stop();
            Console.WriteLine("## {0} Timing: {1}", nameof(MethodInvocationTiming), total.Elapsed);
        }
示例#4
0
        public void MethodLookupTiming()
        {
#if __ANDROID__
            const int count = 100;
#else   // __ANDROID__
            const int count = 100;
#endif  // __ANDROID__

            var total = Stopwatch.StartNew();

            using (var o = new JavaTiming()) {
                var tt = Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    var s = o.Timing_ToString_Traditional();
                    JniObjectReference.Dispose(ref s);
                }
                tt.Stop();

                var ta = Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    var s = o.Timing_ToString_NoCache();
                    JniObjectReference.Dispose(ref s);
                }
                ta.Stop();

                var td = Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    var s = o.Timing_ToString_DictWithLock();;
                    JniObjectReference.Dispose(ref s);
                }
                td.Stop();

                var tc = Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    var s = o.Timing_ToString_DictWithNoLock();
                    JniObjectReference.Dispose(ref s);
                }
                tc.Stop();

                var tp = Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    var s = o.Timing_ToString_JniPeerMembers();
                    JniObjectReference.Dispose(ref s);
                }
                tp.Stop();


                var vtt = Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    o.VirtualIntMethod1Args(i);
                }
                vtt.Stop();

                var vti = Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    o.Timing_VirtualIntMethod_Marshal1Args(i);
                }
                vti.Stop();


                Console.WriteLine("Method Lookup + Invoke Timing:");
                Console.WriteLine("\t   Traditional: {0}", tt.Elapsed);
                Console.WriteLine("\t    No caching: {0}", ta.Elapsed);
                Console.WriteLine("\t  Dict w/ lock: {0}", td.Elapsed);
                Console.WriteLine("\tConcurrentDict: {0}", tc.Elapsed);
                Console.WriteLine("\tJniPeerMembers: {0}", tp.Elapsed);
                Console.WriteLine();
                Console.WriteLine("\t      (I)I virtual+traditional: {0}", vtt.Elapsed);
                Console.WriteLine("\t   (I)I virtual+JniPeerMembers: {0}", vti.Elapsed);
            }
            using (var o = new DerivedJavaTiming()) {
                var ntt = Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    o.VirtualIntMethod1Args(i);
                }
                ntt.Stop();

                var nti = Stopwatch.StartNew();
                for (int i = 0; i < count; ++i)
                {
                    o.Timing_VirtualIntMethod_Marshal1Args(i);
                }
                nti.Stop();
                Console.WriteLine("\t   (I)I nonvirtual+traditional: {0}", ntt.Elapsed);
                Console.WriteLine("\t(I)I nonvirtual+JniPeerMembers: {0}", nti.Elapsed);
            }

            total.Stop();
            Console.WriteLine("## {0} Timing: {1}", nameof(MethodLookupTiming), total.Elapsed);
        }