频繁传递一个64字节的只读结构体,与类引用相比,会产生拷贝开销吗?

编程语言 2026-07-08

我在使用ADO.NET,配合 SqlDataReader。我将数据库行映射到对象,为了避免重复调用 GetOrdinal(),我把列索引缓存在一个辅助类型中。

这个辅助类型只存储从读取器中检索到的列位置:

private readonly struct PersonOrdinals
{
    public readonly int PersonId;
    public readonly int NationalNo;
    public readonly int FirstName;
    public readonly int SecondName;
    public readonly int ThirdName;
    public readonly int LastName;
    public readonly int DateOfBirth;
    public readonly int Gendor;
    public readonly int Email;
    public readonly int NationalityCountryId;
    public readonly int ImagePath;
    public readonly int CreatedAt;
    public readonly int UpdatedAt;
    public readonly int CreatedByUserId;
    public readonly int UpdatedByUserId;
    public readonly int IsActive;
}

该结构体包含16个 int字段(大约64字节)。

在读取行之前,ordinals对象只创建一次:

var ordinals = CreateOrdinals(reader);

然后在映射每一行时会重复传递同一个值:

while (reader.Read())
{
    allPeople.Add(MapPerson(reader, ordinals));
}

映射方法接收缓存的序数对象:

private static Person MapPerson(
    SqlDataReader reader,
    PersonOrdinals ordinals)
{
    // ...
}

我的问题:在每次 MapPerson() 调用时,PersonOrdinals 是否会被拷贝?如果会,在什么情况下将其改为:

private static Person MapPerson(
    SqlDataReader reader,
    in PersonOrdinals ordinals)

与使用类引用相比,这是否会避免可衡量的开销?

我特别关注CLR/JIT行为和参数传递机制,而不是一般的设计建议。

解决方案

Will PersonOrdinals be copied on every MapPerson() call

是的

under what circumstances would changing it to in-parameter avoid measurable overhead compared to using a class reference instead

最佳方法是进行测量。某些情况下,传递引用的大结构体确实有好处,典型的例子是对性能极为敏感、希望尽量避免堆分配的游戏。

请注意,在方法调用时,传递一个结构体的引用与传递一个类引用在性能上应当完全相同。任何性能差异都可能由分配成本、GC成本、内存局部性等因素引起。

对于一个典型的业务应用而言,我怀疑你很难测出使用结构体+ in-参数 与仅使用类之间的差异。很可能你在数据库操作上的任何性能影响都要远大于这点。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章