Zero-Allocation, Ultra-Performance Delegate for C# and Unity
$ dotnet add package LuminDelegate适用于 C# 和 Unity 的零分配、超高性能委托
Zero-Allocation, Ultra-Performance Delegate for C# and Unity
LuminDelegate 是一款基于方法指针的高性能 0GC 委托库,作为 C# 原生委托的全新实现,它在性能与内存控制上实现了突破性优化 —— 对于值类型的委托创建,不同于原生委托会产生装箱操作,LuminDelegate 可完全避免此类开销,且调用速度比原生委托快 50%;对于静态方法,调用效率提升 30%。
LuminDelegate is a high-performance, zero-GC delegate library built on method pointers. As a complete reimagining of C#’s native delegate, it delivers breakthrough optimizations in both speed and memory control: when creating delegates for value types, it completely eliminates the boxing overhead that native delegates incur, while calling them up to 50 % faster; for static methods, invocation efficiency is improved by 30 %.
LuminDelegate具备以下特性:
class Calculator
{
public int Add(int a, int b) => a + b;
public static int Multiply(int a, int b) => a * b;
}
static int HashCode = string.GetHashCode(nameof(Calculator.Add)); // Optional
static void Main()
{
Calculator foo = new Calculator();
using var luminDel = LuminDelegate.CreateFunction<BaseFoo, int, int, int>(foo, nameof(foo.Add), HashCode);
var value = luminDel.Invoke(5, 10);
Console.WriteLine($"实例方法结果:{value} (期望 15)")
}
LuminAction对应原生的Action,应用于无返回值类型。通过LuminDelegate.CreateAction创建。
他有几类泛型参数
public class Foo
{
public int Value;
public void Display() => Console.WriteLine(Value);
}
static void Main()
{
Foo foo = new Foo { Value = 10 };
using var luminDel = LuminDelegate.CreateAction<Foo>(foo, nameof(foo.Add));
luminDel.Invoke();
}
LuminFunction对应原生的Function,应用于有返回值类型。通过LuminDelegate.CreateFunction创建。
他有几类泛型参数
public class Foo
{
public int Value;
public int Display() => Value;
}
static void Main()
{
Foo foo = new Foo { Value = 10 };
using var luminDel = LuminDelegate.CreateFunction<Foo, int>(foo, nameof(foo.Add));
luminDel.Invoke();
}
IL2CPP与.Net, Mono环境不同,因此需要显示调用LuminDelegate.SwitchToIl2Cpp()方法以支持IL2CPP。 两种模式不能混用,不能在Unity Editor或.Net环境下使用IL2CPP模式,否则会导致段报错!
Unity Editor环境下捕获泛型方法,当泛型为引用类型时会段报错。 .Net和IL2CPP环境下没有影响。
LuminDelegate支持捕获Ref Struct类型。
public ref struct Foo
{
public int Value;
public int Display() => Value;
}
static void Main()
{
Foo foo = new Foo { Value = 10 };
using var luminDel = LuminDelegate.CreateFunction<Foo, int>(foo, nameof(foo.Display));
luminDel.Invoke();
}
public class Foo
{
public int Value;
public int Display() => Value;
}
static void Main()
{
Foo foo = new Foo { Value = 10 };
//1.直接传入方法组 (这种方法会产生GC,因为相同于先创建了委托再转成LuminDelegate)
using var luminDel = LuminDelegate.CreateFunction<Foo, int>(foo.Display);
//2.提前创建委托,再传入
Func<int, int> func = foo.Display;
using var luminDel2 = LuminDelegate.CreateFunction<Foo, int>(func);
//3.直接调用原生委托的扩展方法
using var luminDel3 = func.AsLuminFunction<Foo, int>();
}
public class Foo
{
public int Value;
public int Display() => Value;
}
static void Main()
{
Foo foo = new Foo { Value = 10 };
using var luminDel = LuminDelegate.CreateFunction<Foo, int>(foo, nameof(Foo.Display));
var func = luminDel.ToDelegate<Func<int>>(); //泛型参数为委托的具体类型
}
static void Main()
{
//Lambda需把TTarget设为Object
using var luminDel = LuminDelegate.CreateFunction<object?, int int>( (x) => x );
}
public class BaseFoo
{
public virtual int Add(int x) => x;
}
public class Foo : BaseFoo
{
public int Value;
public override int Add(int x) => Value + x;
public static int StaticAdd(int x) => 100 + x;
}
static void Main()
{
BaseFoo instance = new Foo { Value = 10 };
using var luminDel = LuminDelegate.CreateFunction<BaseFoo, int, int>(instance , nameof(Foo.Add));
}
public class Foo
{
public static int StaticAdd(int x) => 100 + x;
}
static void Main()
{
//静态方法不需要传递实例
using var luminDel = LuminDelegate.CreateFunction<Foo, int, int>(nameof(Foo.StaticAdd));
}
This library is licensed under the MIT License.