Skip to content

Commit

Permalink
[Class] Cache the IntPtr constructors in a dictionary. (#5016)
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 #5009.
Fix 2 refers to PR #5013.
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 of multiple fixes for #4936.
  • Loading branch information
rolfbjarne authored Oct 19, 2018
1 parent 1279dd1 commit 097e3fc
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

1 comment on commit 097e3fc

@xamarin-release-manager
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jenkins job (on internal Jenkins) succeeded

Build succeeded
API Diff (from stable)
ℹ️ API Diff (from PR only) (please review changes)
Generator Diff (no change)
Test run succeeded

Please sign in to comment.