c# - 类实例的内存对齐
问题描述
我最近阅读了有关性能的有趣文章。
在那里,作者定义struct
如下:
public struct DecisionTreeNode
{
public short ShortValue;
public float FloatValue;
public byte ByteVal1;
public byte ByteVal2;
}
这struct
是8个字节。
一切都清楚,但随后他建议为了获得性能,作者写道:
这个 [memory] 对齐问题意味着加载未对齐的值可能会更加昂贵。幸运的是,修复非常简单,您只需在类定义中交换字段的顺序。
所以他这样做:
public struct DecisionTreeNode
{
public float FloatValue;
public short ShortValue;
public byte ByteVal1;
public byte ByteVal2;
}
类中字段的顺序如何影响在内存中存储实例的方式?它如何影响提到的对齐?
解决方案
你在这里有一个很好的解释:
https://kalapos.net/Blog/ShowPost/DotNetConceptOfTheWeek13_DotNetMemoryLayout
一切都与 Pack 字段有关(是其最大元素的大小或指定的打包大小属性 => [StructLayout(LayoutKind.Sequential, Pack=X)] 以较小者为准)。
根据 Pack 字段,结构将按顺序将字段分组为 Pack 大小并添加空字节以适应 Pack 字段。
struct => 1byte + 8byte + 1byte => 打包字段 => 8 => 8 + 8 + 8 = 24bytes
struct => 1byte + 1byte + 8byte => Pack 字段 => 8 => 8(1+1+6 个空字节)+ 8 = 16 个字节。
如您所见,始终使用 Pack 字段大小对字段进行分组。
推荐阅读
- reactjs - 在反应状态下使用树结构
- r - 如何在R中重复downSample?
- karate - Android 上的 Gradle 空手道项目找不到功能测试“未收到测试”
- javascript - 模拟输入文本条目的最佳方法
- mysql - 需要有关 SQL 代码的帮助:从昨天开始就一直在这个问题上
- python - 根据横截面设置 Pandas 中子索引的所有值
- javascript - 从 Rails 控制器传递给 Javascript 函数的参数导致“未定义”
- r - 尽管有错误检查和工作简单示例,但 for 循环计算 IRR 中的 R 替换错误
- php - 我想在 php 中更改 3 种不同类型的字体颜色
- excel - 每次出现不同的值时插入分页符