-
Notifications
You must be signed in to change notification settings - Fork 215
Description
Issue Summary
In the current implementation, we need to dynamically execute specific behaviors in generic contexts based on the type being processed. These behaviors include operations such as loading metadata or creating an instance of a C# object from a Swift handle.
The complexity arises because the types can either:
- Originate from Swift (e.g., types conforming to
ISwiftObject). - Be non-Swift types, such as primitive types or C#-specific types that conform to protocols.
Since these cases do not share a common interface or base class, we cannot enforce a shared abstraction to generalize behavior.
Current Approach
The current implementation uses helper classes/methods and leverages MakeGenericType (compatible with NativeAOT) to dynamically dispatch type-specific behavior. The implementation looks like this:
void DoSomething<T>()
{
var type = typeof(T);
if (typeof(ISwiftObject).IsAssignableFrom(type))
{
var helperType = typeof(DoSomethingHelper<>).MakeGenericType(type);
helperType.GetMethod("DoForSwiftObject")!.Invoke(null, null);
}
else
{
// Handle other cases...
}
}This approach ensures compatibility with NativeAOT while working around the limitations of C#, which does not support constructs like:
void DoSomething<T>()
{
if (T is ISwiftObject)
T.DoSomething();
else
// Handle other cases...
}However, this pattern introduces significant performance overhead due to:
- The use of reflection (
MakeGenericType,GetMethod, andInvoke). - The lack of caching, which leads to repeated and unnecessary reflection-based operations.
Problem Statement
The current pattern is slow and poses a significant performance bottleneck. Since the majority of calls into Swift involve this pattern, it impacts the overall efficiency of the system. We need to investigate alternatives or optimizations to reduce the performance overhead.
We already have a cache for this pattern when it comes to TypeMetadata