• 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,
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

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

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

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

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

    #[repr(transparent)]
    struct Newtype(i32);
    
    • 1
    • 2

    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));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

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

    [src/main.rs:13] mem::size_of::<Rust>() = 24
    [src/main.rs:14] mem::offset_of!(Rust, a) = 
    • 1
  • 相关阅读:
    音视频与CPU架构
    ai智能语音机器人实不实用?ai机器人能够为我们带来什么作用?
    微服务不是问题,无能才是!
    2022年零售行业BI商业智能应用白皮书
    Java基础40 断点调试(Debug)
    MyBatis 如何通过拦截器修改 SQL
    设计模式学习笔记 - 组合模式
    pytroch实战12:基于pytorch的网络结构可视化
    【Mycat2实战】三、Mycat实现读写分离
    Apache最新版安装和配置
  • 原文地址:https://blog.csdn.net/wangkai6666/article/details/134489068