用BenchmarkDotNet看Property
屬性——Property,由get,set訪問(wèn)器組成,這是C#使用度比較高的類(lèi)成員。今天分幾組對(duì)比測(cè)試,來(lái)看一下使用Property的性能。
被測(cè)試對(duì)象:
public class MyClass {private string _myProperty1 = DateTime.Now.ToString();public string MyProperty1 { get { return _myProperty1; } }public string MyProperty2 { get { return DateTime.Now.ToString(); } }public string MyMethod(){return DateTime.Now.ToString();} }調(diào)用測(cè)試方法統(tǒng)一如下:
第一組:構(gòu)造實(shí)例化對(duì)象和方法內(nèi)實(shí)例化對(duì)象,調(diào)用屬性差多少
[MemoryDiagnoser] public class TestProperty {private?readonly?MyClass?_myClass;public TestProperty(){_myClass = new MyClass();}[Benchmark]public string PropertyA(){return _myClass.MyProperty1;}[Benchmark]public string PropertyAExt(){var myClass = new MyClass();return myClass.MyProperty1;} }結(jié)果:差別很大,因?yàn)楫吘褂幸粋€(gè)new的過(guò)程,需要開(kāi)銷(xiāo),同時(shí)也能理解,提交初始盡量初始化,多次調(diào)用時(shí)就開(kāi)銷(xiāo)變少了。
第二組:比較用字段屬性和無(wú)字段屬性的差別
[MemoryDiagnoser] public class TestProperty {private readonly MyClass _myClass;public?TestProperty(){_myClass = new MyClass();}[Benchmark]public string PropertyA(){return _myClass.MyProperty1;}[Benchmark]public string PropertyAExt(){var myClass = new MyClass();return myClass.MyProperty1;}[Benchmark]public string PropertyB(){return _myClass.MyProperty2;} [Benchmark]public string PropertyBExt(){var myClass = new MyClass();return myClass.MyProperty2;} }結(jié)果:這組結(jié)果顯示,有字段的屬性更快,因?yàn)楫?dāng)類(lèi)實(shí)體化時(shí),字段的值已經(jīng)初始化完成,所以PropertyA要好于PropertyB,關(guān)于PropertyBExt,初始化字段+實(shí)例化對(duì)象,都占了300ns。
第三組:用反射訪問(wèn)屬性與正常訪問(wèn)屬性對(duì)比
[MemoryDiagnoser] public class TestProperty {private readonly MyClass _myClass;private readonly PropertyInfo _proinfo;public?TestProperty(){_myClass = new MyClass();_proinfo = _myClass.GetType().GetProperty("MyProperty");}[Benchmark]public string PropertyA(){return _myClass.MyProperty1;}[Benchmark]public string PropertyAExt(){var myClass = new MyClass();return myClass.MyProperty1;}[Benchmark]public string PropertyB(){return _proinfo.GetValue(_myClass).ToString();}[Benchmark]public string PropertyBExt(){var myClass = new MyClass();var proinfo = myClass.GetType().GetProperty("MyProperty");return proinfo.GetValue(myClass).ToString();} }結(jié)果:反射調(diào)用肯定要比正常調(diào)用差一些,無(wú)可厚非,僅供參考
第四組:重點(diǎn)看一下代理的性能比較
[MemoryDiagnoser] public class TestProperty {private readonly MyClass _myClass;private readonly PropertyInfo _proinfo;private readonly Func<MyClass, string> _delegate;public TestProperty(){_myClass = new MyClass();_proinfo = _myClass.GetType().GetProperty("MyProperty1");_delegate = (Func<MyClass, string>)Delegate.CreateDelegate(typeof(Func<MyClass, string>), _proinfo.GetGetMethod(true)!);}[Benchmark]public string PropertyA(){return _myClass.MyProperty1;}[Benchmark]public string PropertyAExt(){var myClass = new MyClass();return myClass.MyProperty1;}[Benchmark]public string PropertyB(){return?_proinfo.GetValue(_myClass).ToString();}[Benchmark]public string PropertyBExt(){var myClass = new MyClass();var proinfo = myClass.GetType().GetProperty("MyProperty1");return proinfo.GetValue(myClass).ToString();}[Benchmark]public string PropertyC(){var value = _delegate(_myClass);return value;}[Benchmark]public string PropertyCExt(){var myClass = new MyClass();var proinfo = myClass.GetType().GetProperty("MyProperty1");var dele = (Func<MyClass, string>)Delegate.CreateDelegate(typeof(Func<MyClass, string>), proinfo.GetGetMethod(true)!);return dele(_myClass);} }結(jié)果:PropertyC代理方式與PropertyA接近,看來(lái)在其他場(chǎng)景中可以參考使用。但PropertyCExt要開(kāi)銷(xiāo)的多的多,看來(lái)這是提前在實(shí)例化時(shí)做了工作,所以在代理調(diào)用時(shí)才開(kāi)銷(xiāo)變少。
總結(jié)
以上是生活随笔為你收集整理的用BenchmarkDotNet看Property的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: 开源FastGithub
 - 下一篇: 为什么选择ASP.NET Core