当前位置: 首页 > article >正文

rust内存优化

背景

在 Rust 中,repr 是一个属性(attribute),用于指定数据类型在内存中的布局和表现形式
repr 属性可以用于枚举、结构体和联合体的定义,以控制它们的内部表示方式
repr 属性有多个选项,每个选项对应于一种不同的布局方式

常见的选项包括:

  • C
    将类型按照 C 语言的规则进行布局和对齐。默认的 repr 属性选项。
  • transparent
    将新类型(Newtype)与其内部类型具有相同的内存布局,没有额外的内存开销
  • usize、u8、u16、u32、u64、u128
    指定整数类型的具体大小和表示形式
  • packed
    无对齐的紧密压缩布局,没有填充字节
  • align(n)
    指定对齐方式为 n 字节对齐,其中 n 是 2 的次幂
#[repr(C)]
struct MyStruct {
   
    // 结构体字段
}

#[repr(transparent)]
struct Newtype(i32);

#[repr(packed)]
struct PackedStruct {
   
    // 结构体字段
}

enum MyEnum {
   
    Variant1,
    #[repr(u8)]
    Variant2(u8),
}

union MyUnion {
   
    field1: u8,
    field2: u32,
}

使用不同的 repr 属性选项,来指定不同类型的布局和表示形式
结构体 MyStruct 使用了默认的 C 表示方式
新类型 Newtype 使用了 transparent 表示方式
结构体 PackedStruct 使用了 packed 表示方式
枚举 MyEnum 的 Variant2 使用了 u8 表示方式
联合体 MyUnion 没有指定具体的 repr 属性

通过使用 repr 属性,可以控制数据类型在内存中的布局方式,
这对于与外部代码的交互、内存对齐、硬件访问等场景非常有用
需要谨慎使用 repr 属性,并根据具体的需求选择适当的选项
了解 Rust 的表示属性可以更好地控制数据的内存布局和对齐方式

将新类型(Newtype)与其内部类型具有相同的内存布局?

希望定义一个新类型来提供更好的类型安全性/表示特定的语义,但又不想引入额外的内存开销
通过使用 #[repr(transparent)] 属性,确保新类型与其内部类型的内存布局完全相同
即没有任何额外的包装或填充字节
对于在代码中传递特定类型的参数、避免不必要的包装和解包以及与其它代码进行互操作性非常有用

#[repr(transparent)]
struct Newtype(i32);

Newtype 的新类型,内部包含了一个 i32 类型的字段
告诉编译器新类型 Newtype 的大小和对齐方式与 i32 完全相同

注意
#[repr(transparent)] 属性只适用于具有单个字段的新类型
且该字段的类型和新类型的类型必须是安全的(即无内部可变性和其他危险的属性)

介绍

对于不带标记的数据结构,默认 repr
repr 代表 rust 可以任意优化内存布局,对内部数据进行重排
保证其内部空间尽量紧凑,不包含过多的 padding

struct Rust {
   
#![feature(offset_of)]

use std::mem;

struct Rust {
   
 a: u64,
 b: bool,
 c: u64,
 d: bool,
}

fn main() {
   
    dbg!(mem::size_of::<Rust>());
    dbg!(mem::offset_of!(Rust, a));
    dbg!(mem::offset_of!(Rust, b));
    dbg!(mem::offset_of!(Rust, c));
    dbg!(mem::offset_of!(Rust, d));
}

在不带 repr© 时,rust 会对其中的 field 进行重排

[src/main.rs:13] mem::size_of::<Rust>() = 24
[src/main.rs:14] mem::offset_of!(Rust, a) = 

http://www.kler.cn/a/133599.html

相关文章:

  • netmap.js:基于浏览器的网络发现工具
  • git入门环境搭建
  • 穿越数据迷宫:C++哈希表的奇幻旅程
  • 使用API有效率地管理Dynadot域名,编辑账户中whois联系人信息
  • 鸿蒙HarmonyOS 地图不显示解决方案
  • 鸿蒙next版开发:相机开发-适配不同折叠状态的摄像头变更(ArkTS)
  • .NET CLR介绍
  • 处理多个axios请求
  • Hive 定义变量 变量赋值 引用变量
  • centos 安装 docker
  • echarts双轴刻度线y轴刻度线对齐
  • 支持4KHz回报还能无线充电,简约不简单的雷柏VT3S游戏鼠标上手
  • Mongodb 副本集名称重命名
  • Vue3 动态设置 ref
  • 2018年五一杯数学建模C题江苏省本科教育质量综合评价解题全过程文档及程序
  • 使用html2canvas转换table为图片时合并单元格rowspan失效,无边框显示问题解决(React实现)
  • python从基础到UnitTest框架-python基础语法
  • iOS_折叠展开 FoldTextView
  • 手机LiDAR-based激光雷达标定板提高无人汽车智能化程度
  • Nas搭建webdav服务器并同步Zotero科研文献
  • 持续集成部署-k8s-配置与存储-配置管理:SubPath
  • 新版JetBrains ToolBox【Windows】修改应用安装位置
  • Node.js之path路径模块
  • ubuntu22.04换源
  • NSSCTF第13页(2)
  • 音视频项目—基于FFmpeg和SDL的音视频播放器解析(十二)