生活随笔
收集整理的這篇文章主要介紹了
反射,Expression Tree,IL Emit 属性操作对比
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
.net的反射(Reflection) 是.Net中獲取運(yùn)行時(shí)類型信息的一種方法,通過(guò)反射編碼的方式可以獲得 程序集,模塊,類型,元數(shù)據(jù)等信息。
反射的優(yōu)點(diǎn)在于微軟提供的API調(diào)用簡(jiǎn)單,使用方便;
表達(dá)式樹(shù)(Expression Tree)表達(dá)式樹(shù)以樹(shù)形數(shù)據(jù)結(jié)構(gòu)表示代碼,其中每一個(gè)節(jié)點(diǎn)都是一種表達(dá)式,表達(dá)式樹(shù)經(jīng)過(guò)編譯后生成的直接是IL代碼;
IL Emit 是直接操作IL的執(zhí)行過(guò)程,對(duì)IL代碼精細(xì)化控制;
屬性賦值操作 PropertyInfo.GetValue/SetValue是反射中常用的功能;
三種實(shí)現(xiàn)方式的性能對(duì)比:
public class Bar{public int Id { get; set; }public string Name { get; set; }}public class Foo{public Bar Bar { get; set; }public static void SetReflection(Foo foo, Bar bar){var property = foo.GetType().GetProperty("Bar");property.SetValue(foo, bar);}public static Action<Foo, Bar> SetExpression(){var property = typeof(Foo).GetProperty("Bar");var target = Expression.Parameter(typeof(Foo));ParameterExpression propertyValue = Expression.Parameter(typeof(Bar));//var setPropertyValue = Expression.Call(target, property.GetSetMethod(), propertyValue);BinaryExpression setPropertyValue = Expression.Assign(Expression.Property(target, property), propertyValue);var setAction = Expression.Lambda<Action<Foo, Bar>>(setPropertyValue, target, propertyValue).Compile();return setAction;}public static Action<Foo, Bar> SetEmit(){var property = typeof(Foo).GetProperty("Bar");DynamicMethod method = new DynamicMethod("SetValue", null, new Type[] { typeof(Foo), typeof(Bar) });ILGenerator ilGenerator = method.GetILGenerator();ilGenerator.Emit(OpCodes.Ldarg_0);ilGenerator.Emit(OpCodes.Ldarg_1);ilGenerator.EmitCall(OpCodes.Callvirt, property.GetSetMethod(), null);ilGenerator.Emit(OpCodes.Ret);method.DefineParameter(1, ParameterAttributes.In, "obj");method.DefineParameter(2, ParameterAttributes.In, "value");var setAction2 = (Action<Foo, Bar>)method.CreateDelegate(typeof(Action<Foo, Bar>));return setAction2;}public static void Test(){var act1 = Foo.SetExpression();var act2 = Foo.SetEmit();var st = new Stopwatch();st.Start();for (int i = 0; i < 1000000; i++){var foo = new Foo { };var bar = new Bar { Id = 1, Name = "name" };Foo.SetReflection(foo, bar);}Console.WriteLine("Reflection " + st.ElapsedMilliseconds);st.Restart();for (int i = 0; i < 1000000; i++){var foo = new Foo { };var bar = new Bar { Id = 1, Name = "name" };act1(foo, bar);}Console.WriteLine("Expression " + st.ElapsedMilliseconds);st.Restart();for (int i = 0; i < 1000000; i++){var foo = new Foo { };var bar = new Bar { Id = 1, Name = "name" };act2(foo, bar);}Console.WriteLine("Emit " + st.ElapsedMilliseconds);}}
循環(huán)多次操作性能對(duì)比還是明顯的表達(dá)式數(shù)和emit的性能優(yōu)勢(shì)明顯;
測(cè)試結(jié)果
但是只循環(huán)一次的話 三種實(shí)現(xiàn)方式性能是無(wú)差別的,所以在一般情況下,反射的性能損失是可以忽略的;
轉(zhuǎn)載于:https://www.cnblogs.com/sands/p/11373569.html
總結(jié)
以上是生活随笔為你收集整理的反射,Expression Tree,IL Emit 属性操作对比的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。