[ObjCRuntime] Cache a few expensive and frequent operations in Class. Fixes #19079. by rolfbjarne · Pull Request #19086 · dotnet/macios (original) (raw)
Cache:
- Assembly -> assembly name, because Assembly.GetName ().Name is quite slow.
- Token reference -> member lookup, because it takes a non-significant amount
of time to do the lookup each time.
Assembly.GetName ().Name used to be 75% of the time in Runtime.GetINativeObject_Static:
Text table:
| 6.82 s | 100.0% | 0 s | MauiBugiOSInteropPerformance (17191)
| 6.82 s | 100.0% | 0 s | Main Thread 0x4a830e
| 6.82 s | 100.0% | 1.00 ms | xamarin_get_inative_object_static
| 6.80 s | 99.8% | 0 s | wrapper_native_to_managed_ObjCRuntime_Runtime_get_inative_object_static_intptr_sbyte_uint_uint_intptr_
| 6.79 s | 99.6% | 2.00 ms | ObjCRuntime_Runtime_get_inative_object_static_intptr_sbyte_uint_uint_intptr_
| 6.79 s | 99.5% | 3.00 ms | ObjCRuntime_Runtime_GetINativeObject_Static_intptr_sbyte_uint_uint
| 4.23 s | 62.0% | 4.00 ms | ObjCRuntime_Class_ResolveTypeTokenReference_uint
| 4.23 s | 62.0% | 8.00 ms | ObjCRuntime_Class_ResolveTokenReference_uint_uint
| 4.07 s | 59.7% | 0 s | ObjCRuntime_Class_ResolveAssembly_intptr
| 4.07 s | 59.7% | 25.00 ms | ObjCRuntime_Class_TryResolveAssembly_intptr_System_Reflection_Assembly_
| 3.35 s | 49.2% | 22.00 ms | System_Reflection_Assembly_GetName
| 668.00 ms | 9.8% | 0 s | System_AppDomain_GetAssemblies
| 25.00 ms | 0.3% | 25.00 ms | ObjCRuntime_Runtime_StringEquals_intptr_string
| 107.00 ms | 1.5% | 5.00 ms | ObjCRuntime_Class_ResolveModule_System_Reflection_Assembly_uint
| 40.00 ms | 0.5% | 0 s | ObjCRuntime_Class_ResolveToken_System_Reflection_Module_uint
| 1.00 ms | 0.0% | 1.00 ms | plt_ObjCRuntime_Class_ResolveToken_System_Reflection_Module_uint
| 2.54 s | 37.3% | 3.00 ms | ObjCRuntime_Runtime_GetINativeObject_intptr_bool_System_Type_System_Type
| 2.33 s | 34.2% | 1.00 ms | ObjCRuntime_Runtime_LookupINativeObjectImplementation_intptr_System_Type_System_Type_bool
| 2.32 s | 33.9% | 1.00 ms | ObjCRuntime_Runtime_FindProtocolWrapperType_System_Type
| 2.12 s | 31.0% | 1.00 ms | ObjCRuntime_Class_ResolveTypeTokenReference_uint
| 2.12 s | 31.0% | 7.00 ms | ObjCRuntime_Class_ResolveTokenReference_uint_uint
| 2.04 s | 29.9% | 1.00 ms | ObjCRuntime_Class_ResolveAssembly_intptr
| 2.04 s | 29.9% | 13.00 ms | ObjCRuntime_Class_TryResolveAssembly_intptr_System_Reflection_Assembly_
| 1.69 s | 24.8% | 19.00 ms | System_Reflection_Assembly_GetName
| 1.67 s | 24.5% | 9.00 ms | System_Reflection_RuntimeAssembly_GetName_bool
| 872.00 ms | 12.7% | 16.00 ms | System_Reflection_AssemblyName_Create_intptr_string
| 791.00 ms | 11.6% | 1.00 ms | System_Reflection_RuntimeAssembly_GetInfo_System_Reflection_RuntimeAssembly_AssemblyInfoKind
| 319.00 ms | 4.6% | 1.00 ms | System_AppDomain_GetAssemblies
| 14.00 ms | 0.2% | 14.00 ms | ObjCRuntime_Runtime_StringEquals_intptr_string
| 4.00 ms | 0.0% | 4.00 ms | plt_ObjCRuntime_Runtime_StringEquals_intptr_string
| 54.00 ms | 0.7% | 0 s | ObjCRuntime_Class_ResolveModule_System_Reflection_Assembly_uint
| 15.00 ms | 0.2% | 1.00 ms | ObjCRuntime_Class_ResolveToken_System_Reflection_Module_uint
and Class.ResolveTokenReference was 90% of the time in Runtime.GetINativeObject_Static:
| 6.82 s | 100.0% | 0 s | MauiBugiOSInteropPerformance (17191)
| 6.82 s | 100.0% | 0 s | Main Thread 0x4a830e
| 6.82 s | 100.0% | 1.00 ms | xamarin_get_inative_object_static
| 6.80 s | 99.8% | 0 s | wrapper_native_to_managed_ObjCRuntime_Runtime_get_inative_object_static_intptr_sbyte_uint_uint_intptr_
| 6.79 s | 99.6% | 2.00 ms | ObjCRuntime_Runtime_get_inative_object_static_intptr_sbyte_uint_uint_intptr_
| 6.79 s | 99.5% | 3.00 ms | ObjCRuntime_Runtime_GetINativeObject_Static_intptr_sbyte_uint_uint
| 4.23 s | 62.0% | 4.00 ms | ObjCRuntime_Class_ResolveTypeTokenReference_uint
| 4.23 s | 62.0% | 8.00 ms | ObjCRuntime_Class_ResolveTokenReference_uint_uint
| 2.54 s | 37.3% | 3.00 ms | ObjCRuntime_Runtime_GetINativeObject_intptr_bool_System_Type_System_Type
| 2.33 s | 34.2% | 1.00 ms | ObjCRuntime_Runtime_LookupINativeObjectImplementation_intptr_System_Type_System_Type_bool
| 2.32 s | 33.9% | 1.00 ms | ObjCRuntime_Runtime_FindProtocolWrapperType_System_Type
| 2.12 s | 31.0% | 1.00 ms | ObjCRuntime_Class_ResolveTypeTokenReference_uint
| 2.12 s | 31.0% | 7.00 ms | ObjCRuntime_Class_ResolveTokenReference_uint_uint
| 181.00 ms | 2.6% | 4.00 ms | ObjCRuntime_Class_GetTokenReference_System_Type_bool
| 11.00 ms | 0.1% | 0 s | wrapper_managed_to_native_ObjCRuntime_Runtime_xamarin_find_protocol_wrapper_type_uint
| 3.00 ms | 0.0% | 0 s | System_Type_get_IsInterface
| 1.00 ms | 0.0% | 1.00 ms | plt_System_Type_get_IsByRef
| 1.00 ms | 0.0% | 1.00 ms | System_Type_get_IsByRef
| 10.00 ms | 0.1% | 0 s | System_RuntimeType_IsAssignableFrom_System_Type
| 5.00 ms | 0.0% | 0 s | System_Type_get_IsInterface
| 2.00 ms | 0.0% | 0 s | System_Type_get_IsByRef
| 192.00 ms | 2.8% | 3.00 ms | ObjCRuntime_Runtime_ConstructINativeObject_T_REF_intptr_bool_System_Type_ObjCRuntime_Runtime_MissingCtorResolution
| 8.00 ms | 0.1% | 1.00 ms | ObjCRuntime_Runtime_TryGetNSObject_intptr_bool
| 4.00 ms | 0.0% | 1.00 ms | System_RuntimeType_IsSubclassOf_System_Type
| 1.00 ms | 0.0% | 1.00 ms | mono_monitor_enter_v4_fast
| 8.00 ms | 0.1% | 3.00 ms | ObjCRuntime_Runtime_AllocGCHandle_object_System_Runtime_InteropServices_GCHandleType
| 1.00 ms | 0.0% | 1.00 ms | plt_ObjCRuntime_Runtime_AllocGCHandle_object_System_Runtime_InteropServices_GCHandleType
| 9.00 ms | 0.1% | 0 s | mono_threads_detach_coop
| 5.00 ms | 0.0% | 0 s | mono_threads_attach_coop
| 12.00 ms | 0.1% | 1.00 ms | xamarin_gchandle_unwrap
There's some overlap here - the Assembly.GetName ().Name cache would be redundant if it was only called from Class.ResolveTokenReference - but since it's called in more places (it still shows up in profiles once Class.ResolveTokenReference is cached), I kept both caches.
Fixes #19079.