通过属性访问指针字段

问题描述 投票:0回答:1

在这种情况下是否可以避免属性方法调用的开销(以某种方式强制编译器内联?我知道这更像是别名,但 C# 中没有这样的东西):

unsafe public static class Results
{
    public static void Test()
    {
        var cstruct = new CStruct();
        var obj     = new WrapperForCStruct(&cstruct);
        var x       = obj.Field;
        var y       = obj.ptr->field;
    }
}

public struct CStruct
{
    public int field;
}

unsafe public sealed class WrapperForCStruct(CStruct* pointer)
{
    public CStruct* ptr = pointer;

    public int Field => ptr->field;
}

与 obj.ptr->field 相比,访问 obj.Field 有开销:

IL(锐实验室)

var x = obj.Field;
IL_0010: dup
IL_0011: callvirt instance int32 WrapperForCStruct::get_Field()
IL_0016: pop

var y = obj.ptr->field;
IL_0017: ldfld valuetype CStruct* WrapperForCStruct::ptr
IL_001c: ldobj CStruct
IL_0021: pop

反汇编(发布-优化)

var x = obj.Field;
00007FFDB5C43E96  mov         rcx,qword ptr [rbp-10h]  
00007FFDB5C43E9A  cmp         dword ptr [rcx],ecx  
00007FFDB5C43E9C  call        qword ptr [CLRStub[MethodDescPrestub]@00007FFDB5E4D5F0 (07FFDB5E4D5F0h)]  
00007FFDB5C43EA2  mov         dword ptr [rbp-14h],eax  
00007FFDB5C43EA5  nop  

var y = obj.ptr->field;
00007FFDB4223E97  mov         rcx,qword ptr [rbp-10h]  
00007FFDB4223E9B  mov         rcx,qword ptr [rcx+8]  
00007FFDB4223E9F  cmp         byte ptr [rcx],cl  
c# performance
1个回答
0
投票

在这种情况下,我实际上会执行托管指针,并将 WrapperForCStruct 设置为

ref struct
。这样我们就可以拥有
ref field
而不是属性。有了满口的
readonly
修饰符,我们就有了一个“吸气剂”。

struct CStruct {
    public int field;
}

ref struct WrapperForCStruct {
    public readonly ref readonly int Field;
    public WrapperForCStruct(ref CStruct cstruct) {
        Field = ref cstruct.field;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.