生活随笔
收集整理的這篇文章主要介紹了
反射,Expression Tree,IL Emit 属性操作对比
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
.net的反射(Reflection) 是.Net中獲取運行時類型信息的一種方法,通過反射編碼的方式可以獲得 程序集,模塊,類型,元數據等信息。
反射的優點在于微軟提供的API調用簡單,使用方便;
表達式樹(Expression Tree)表達式樹以樹形數據結構表示代碼,其中每一個節點都是一種表達式,表達式樹經過編譯后生成的直接是IL代碼;
IL Emit 是直接操作IL的執行過程,對IL代碼精細化控制;
屬性賦值操作 PropertyInfo.GetValue/SetValue是反射中常用的功能;
三種實現方式的性能對比:
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);}}
循環多次操作性能對比還是明顯的表達式數和emit的性能優勢明顯;
測試結果
但是只循環一次的話 三種實現方式性能是無差別的,所以在一般情況下,反射的性能損失是可以忽略的;
轉載于:https://www.cnblogs.com/sands/p/11373569.html
總結
以上是生活随笔為你收集整理的反射,Expression Tree,IL Emit 属性操作对比的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。