@@ -107,6 +107,8 @@ To run a specific test fixture, set the FIXTURE variable:
107
107
108
108
## Notes
109
109
110
+ ### JDK and Global References
111
+
110
112
The JDK VM supports an effectively unlimited number of global references.
111
113
While Dalvik craps out after creating ~ 64k GREFs, consider the following
112
114
on the JDK:
@@ -127,3 +129,45 @@ I killed the above loop after reaching 25686556 instances.
127
129
128
130
I'm not sure when the JDK would stop handing out references, but it's probably
129
131
bound to process heap limits (e.g. depends on 32-bit vs. 64-bit process).
132
+
133
+ ### JNI Invocation Overhead
134
+
135
+ [ tests/PerformanceTests/TimingTests.cs] ( tests/PerformanceTests/TimingTests.cs )
136
+ contains various tests to investigate the overheads involved in using JNI to
137
+ invoke Java methods. In particular, see the
138
+ ` Java.Interop.PerformanceTests.JniMethodInvocationOverheadTiming.MethodInvocationTiming() `
139
+ tests, invokes a JNI method ` count ` times and attempts to "normalize" that to
140
+ invoking an equivalent, non-inlined, C# method.
141
+
142
+ [ Commit c60f6093] [ c60f6093 ] observed that Android appeared to be much faster
143
+ than the JVM at these tests. This observation appears to have been wrong.
144
+ More interesting is that the "JNI method invocation overhead," defined as
145
+ what this test is attempting to measure (which may be wrong!), varies
146
+ based on the number of method invocations.
147
+
148
+ [ c60f6093 ] : https://github.com/xamarin/Java.Interop/commit/c60f6093
149
+
150
+ For example, if we look at just the summary information of one test
151
+ as we vary the value of ` count ` , the number of times we invoke the
152
+ Java method via JNI or the C# method, we see that there is a nonlinear
153
+ relationship between the count and the overhead:
154
+
155
+ count= 10: Method Invoke: static void i3: JNI is 5x managed
156
+ count= 100: Method Invoke: static void i3: JNI is 10x managed
157
+ count= 500: Method Invoke: static void i3: JNI is 22x managed
158
+ count= 1000: Method Invoke: static void i3: JNI is 63x managed
159
+ count= 10000: Method Invoke: static void i3: JNI is 474x managed
160
+ count=100000: Method Invoke: static void i3: JNI is 808x managed
161
+
162
+ Particularly troubling is the * huge* jump between count=1000 and
163
+ count=10000. Count=1000000 is provided for comparison with the JVM,
164
+ which provides the following results:
165
+
166
+ count=1000000: Method Invoke: static void i3: JNI is 413x managed [JVM]
167
+
168
+ We don't know why there's a jump, but this is in fact somewhat encouraging:
169
+ if you're only calling methods in a one-off fashion -- as is frequently
170
+ the case in Xamarin.Android -- then the overhead isn't actually that bad,
171
+ on a per-method invoke basis. It appears to only get really bad when
172
+ invoking the same method repetitively, * a lot* , which I believe shouldn't
173
+ be * that* common a use case (outside of image manipulation?).
0 commit comments