用BenchmarkDotNet看Property

属性——Property,由get,set访问器组成,这是C#使用度比较高的类成员。今天分几组对比测试,来看一下使用Property的性能。

被测试对象:

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();
    }
}

调用测试方法统一如下:

BenchmarkRunner.Run<TestProperty>();

第一组:构造实例化对象和方法内实例化对象,调用属性差多少

[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;
    }
}

结果:差别很大,因为毕竟有一个new的过程,需要开销,同时也能理解,提交初始尽量初始化,多次调用时就开销变少了。

第二组:比较用字段属性和无字段属性的差别

[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;
    }
}

结果:这组结果显示,有字段的属性更快,因为当类实体化时,字段的值已经初始化完成,所以PropertyA要好于PropertyB,关于PropertyBExt,初始化字段+实例化对象,都占了300ns。


第三组:用反射访问属性与正常访问属性对比

[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();
    }
}

结果:反射调用肯定要比正常调用差一些,无可厚非,仅供参考

第四组:重点看一下代理的性能比较

[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);
    }
}

结果:PropertyC代理方式与PropertyA接近,看来在其他场景中可以参考使用。但PropertyCExt要开销的多的多,看来这是提前在实例化时做了工作,所以在代理调用时才开销变少。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值