-
Notifications
You must be signed in to change notification settings - Fork 501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Abysmal performance in Interop on iOS #19079
Comments
From @drasticactions on Thu, 21 Sep 2023 03:10:26 GMT This doesn't seem to be a MAUI UI issue, but a xamarin-macios one or maybe a runtime issue? @rolfbjarne What are your thoughts on this? |
From @rolfbjarne on Thu, 21 Sep 2023 07:13:19 GMT I tried your project, but it seems you need to check in the nupkg too:
I have a suggestion though to try to improve performance: disable the interpreter and use the static registrar: <PropertyGroup>
<UseInterpreter>false</UseInterpreter>
<Registrar>static</Registrar>
</PropertyGroup> that should speed up execution. |
From @damiand2 on Thu, 21 Sep 2023 07:35:36 GMT @rolfbjarne - sorry for nupkg, you can try again, file is uploaded now. |
From @rolfbjarne on Thu, 21 Sep 2023 09:59:30 GMT I can reproduce this, moving to the correct repo. |
…ixes xamarin#19079. 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. Fixes xamarin#19079.
I've implemented a few fixes that should help this scenario, we'll try to get them in .NET 8. In any case, here's a workaround that seems to completely solve the problem: https://gist.github.com/rolfbjarne/3feeee9ba3da58f9fca3a6976b96a4c1 |
thanks @rolfbjarne . Please let me know when you will know if perf fixes will be in .net 8 GA - and therefore if those manual calls to objc_msgSend will be needed |
…ixes #19079. (#19086) 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: ![Screenshot 2023-09-21 at 17 55 07](https://github.com/xamarin/xamarin-macios/assets/249268/87d456a6-9aa6-4a00-8631-d125eb4b70c2) 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: ![Screenshot 2023-09-21 at 17 55 40](https://github.com/xamarin/xamarin-macios/assets/249268/75adc9bf-ca5b-4bc6-96c6-ace4cb39a0d4) ``` | 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. --------- Co-authored-by: Manuel de la Pena <mandel@microsoft.com>
No, these perf fixes will not be in .NET 8 GA, it's a bit too late and risky at this point. We'll try to get them into a .NET 8 service release though. |
From @damiand2 on Wed, 20 Sep 2023 14:59:32 GMT
Description
During tests on iOS for self made binding library that binds to xcframework for google map utils (https://github.com/googlemaps/google-maps-ios-utils) i found that application slows down to a crawl in specific scenario. After instrumenting app (Instruments on macos) i found that that perf drop was related to switch between my code and native one (overriding method on class that binds to native one). After removal of that override, app is fast again.
This kind of interop was also used on Xamarin.Forms (albeit with different binding library and earlier native library version) and there were no problems. Sample screen from Instruments showing dramatic cpu time in specific runtime methods responsible for interop between .net and native code:
Steps to Reproduce
Link to public reproduction project repository
https://github.com/damiand2/MauiBugiOSInteropPerformance
Version with bug
7.0.92
Is this a regression from previous behavior?
Yes, this used to work in Xamarin.Forms
Last version that worked well
Unknown/Other
Affected platforms
iOS
Affected platform versions
No response
Did you find any workaround?
No response
Relevant log output
No response
Copied from original issue dotnet/maui#17516
The text was updated successfully, but these errors were encountered: