-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Was toying with the code and was looking at how akka dealt with Unity / IL2CPP on windows with a simple Actor. Everything works fine in the Unity Editor, but unfortunately, after ahead of time compilation, I was greeted with the kiss of death for AOT - Reflection.Emit. I started peeking at the code and saw that there was a lot of lambda compilation caching which can somewhat be an anti-pattern if you're using it from syntactic sugar. That arose the secondary issue - if you're using Expression<Func<>> or anything of the like, you're generating a completely new set of objects on every single call regardless of whether they are compiled or not later. If you run the code below, you'll see you get a fresh hashcode. If you crack the actual code in .NET for expressions, you'll see that the static methods for the lambdas are inserted inline, and you get a heap of allocations for even the smallest of lambdas.
Expression<Func<int>> expression = Expression.Lambda<Func<int>>(Expression.Constant(1, typeof(int)), Array.Empty<ParameterExpression>());
Regardless of whether this gets closed, it would be good to address the AOT situation in the readme. AOT is becoming more and more of an issue these days and it took more than a few hours to run into this, unfortunately.
Would be great if there was a way to avoid the reflection.emit paths and/or provide an alternative.
class Program
{
private static List<Expression> _expressions = new List<Expression>();
private static void Main(string[] args)
{
for (int i = 0; i < 1000000; i++)
{
Expression<Func<int>> expression = () => 1;
Console.WriteLine(expression.GetHashCode());
_expressions.Add(expression);
}
}
}