Skip to content

Commit

Permalink
[Class] Cache the IntPtr constructors in a dictionary.
Browse files Browse the repository at this point in the history
Using reflection to find these constructors is computation-intensitive, so
cache the results.

Numbers
=======

Test case: rolfbjarne/TestApp@004283d

Fix 1 refers to PR xamarin#5009.
Fix 2 refers to PR #?
Fix 3 is this fix.

iPad Air 2
----------

| Configuration       | Before | After fix 1 | After fix 2  | After fix 3  | Improvement from fix 2 to fix 3 | Cumulative improvement |
| ------------------- | ------ | ----------: | -----------: | -----------: | ------------------------------: | ---------------------: |
| Release (link all)  | 477 ms |      481 ms |       224 ms |       172 ms |                     52 ms (23%) |           305 ms (64%) |
| Release (dont link) | 738 ms |      656 ms |       377 ms |       201 ms |                    176 ms (47%) |           537 ms (73%) |

iPhone X
--------

| Configuration       | Before | After fix 1 | After fix 2  | After fix 3  | Improvement from fix 2 to fix 3 | Cumulative improvement |
| ------------------- | ------ | ----------: | -----------: | -----------: | ------------------------------: | ---------------------: |
| Release (link all)  |  98 ms |       99 ms |        42 ms |        31 ms |                     11 ms (26%) |            67 ms (68%) |
| Release (dont link) | 197 ms |      153 ms |        91 ms |        43 ms |                     48 ms (53%) |           154 ms (78%) |

When linking all assemblies, the type map has 24 entries, and when not linking
at all it has 2993 entries.

This is part 3 (the last) of multiple fixes for xamarin#4936.
  • Loading branch information
rolfbjarne committed Oct 19, 2018
1 parent cb4ca0f commit c0d8d9b
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions src/ObjCRuntime/Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public partial class Runtime {
#endif

static Dictionary<IntPtrTypeValueTuple,Delegate> block_to_delegate_cache;
static Dictionary<Type, ConstructorInfo> intptr_ctor_cache;
static Dictionary<Type, ConstructorInfo> intptr_bool_ctor_cache;

static List <object> delegates;
static List <Assembly> assemblies;
Expand Down Expand Up @@ -239,6 +241,8 @@ unsafe static void Initialize (InitializationOptions* options)
Runtime.options = options;
delegates = new List<object> ();
object_map = new Dictionary <IntPtr, WeakReference> (IntPtrEqualityComparer);
intptr_ctor_cache = new Dictionary<Type, ConstructorInfo> (TypeEqualityComparer);
intptr_bool_ctor_cache = new Dictionary<Type, ConstructorInfo> (TypeEqualityComparer);
lock_obj = new object ();

NSObjectClass = NSObject.Initialize ();
Expand Down Expand Up @@ -1152,22 +1156,36 @@ static T ConstructINativeObject<T> (IntPtr ptr, bool owns, Type type, MissingCto

static ConstructorInfo GetIntPtrConstructor (Type type)
{
lock (intptr_ctor_cache) {
if (intptr_ctor_cache.TryGetValue (type, out var rv))
return rv;
}
var ctors = type.GetConstructors (BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
for (int i = 0; i < ctors.Length; ++i) {
var param = ctors[i].GetParameters ();
if (param.Length == 1 && param [0].ParameterType == typeof (IntPtr))
if (param.Length == 1 && param [0].ParameterType == typeof (IntPtr)) {
lock (intptr_ctor_cache)
intptr_ctor_cache [type] = ctors [i];
return ctors [i];
}
}
return null;
}

static ConstructorInfo GetIntPtr_BoolConstructor (Type type)
{
lock (intptr_bool_ctor_cache) {
if (intptr_bool_ctor_cache.TryGetValue (type, out var rv))
return rv;
}
var ctors = type.GetConstructors (BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
for (int i = 0; i < ctors.Length; ++i) {
var param = ctors[i].GetParameters ();
if (param.Length == 2 && param [0].ParameterType == typeof (IntPtr) && param [1].ParameterType == typeof (bool))
if (param.Length == 2 && param [0].ParameterType == typeof (IntPtr) && param [1].ParameterType == typeof (bool)) {
lock (intptr_bool_ctor_cache)
intptr_bool_ctor_cache [type] = ctors [i];
return ctors [i];
}
}
return null;
}
Expand Down

0 comments on commit c0d8d9b

Please sign in to comment.