.net中反射、emit、expression和dynamic的性能比较

复制代码
class Student
{
public string Name { get; set; }
}

static double Test(int loop, Student stu, Func<Student, string> action)
{
var watch
= Stopwatch.StartNew();
string s = null;
for (var i = 0; i < loop; i++)
s
= action(stu);

return watch.ElapsedTicks;
}

static Func<Student, string> NativeGetter()
{
return s => s.Name;
}

static Func<Student, string> ReflectedGetter()
{
var type
= typeof (Student);
var prop
= type.GetProperty("Name");

return s => (string)prop.GetValue(s, null);
}

static Func<Student, string> EmittedGetter()
{
var dm
= new DynamicMethod(name: "EmittedGetter", returnType: typeof(string), parameterTypes: new[] { typeof(Student) }, owner: typeof(Student));

var type
= typeof (Student);
var prop
= type.GetMethod("get_Name");
var il
= dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, prop);
il.Emit(OpCodes.Ret);

return (Func<Student, string>)dm.CreateDelegate(typeof(Func<Student, string>));
}

static Func<Student, string> ExpressionGetter()
{
var type
= typeof(Student);
var prop
= type.GetMethod("get_Name");

ParameterExpression pa
= Expression.Parameter(typeof(Student));
Expression body
= Expression.Call(pa, prop);

return Expression.Lambda<Func<Student, string>>(body, pa).Compile();
}

static Func<Student, string> DynamicGetter()
{
return s => { dynamic d = s; return d.Name; };
}

[MethodImpl(MethodImplOptions.NoOptimization)]
public static void Run()
{
const int loop = 5000000;

var stu
= new Student {Name = "Mike"};

var dynamic
=
Test(loop, stu, DynamicGetter());

var expression
=
Test(loop, stu, ExpressionGetter());

var native
=
Test(loop, stu, NativeGetter());

var emitted
=
Test(loop, stu, EmittedGetter());

var reflected
=
Test(loop, stu, ReflectedGetter());

Console.WriteLine(
"native:{0}\ndynamic:{1}\nemit:{2}\nexpression:{3}\nreflection:{4}", 1, dynamic / native, emitted / native, expression / native, reflected / native);

Console.ReadKey();
}
复制代码

测试结果

1. 当循环次数比较小的时候, loop=1000

native:1
dynamic:540.444964871194
emit:0.704918032786885
expression:0.224824355971897
reflection:8.37002341920375

2. loop=5000000

native:1
dynamic:4.37328053807767
emit:0.96159470600998
expression:1.00412887828162
reflection:35.909097418095

posted @   dragonpig  阅读(1710)  评论(2编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示