返回文章列表

文章

Zig中的列表

目录
  1. 1. Zig 列表/容器类型概述
  2. 1.1 固定长度数组 [N]T
  3. 1.2 切片 []T
  4. 1.3 动态数组 std.ArrayList(T)
  5. 1.4 双端队列 std.DequeList(T)
  6. 1.5 SIMD 向量 @Vector(T, N)
  7. 2. 五种类型对比表
  8. 3. 其他语言中的 SIMD 向量对照
  9. 现代语言都在尝试“一套代码映射最优指令集”,以提升可移植性与性能。
  10. 4. 场景选型建议

1. Zig 列表/容器类型概述#

下面从 定义与底层映射内存布局与所有权操作与语法 三个维度,逐一介绍 Zig 中常见的五种列表或容器类型:

类型简称
固定长度数组[N]T
切片[]T
动态数组std.ArrayList(T)
双端队列std.DequeList(T)
SIMD 向量@Vector(T, N)

1.1 固定长度数组 [N]T#

  • 定义与底层映射

const A = [5]u8; // 在编译期确定长度 5 的无符号字节数组 ``` 编译后映射为 LLVM <5 x i8>(在结构体或局部变量中则按连续元素展平)。

  • 内存布局与所有权
    • 存储位置:栈上(或全局/结构体内)
    • 所有权:值类型,拷贝即复制所有元素
    • 对齐:按元素类型对齐
  • 操作与语法
    • 索引:a[2]
    • 迭代:for (a) |elem| …
    • 固定长度,不能增删

1.2 切片 []T#

  • 定义与底层映射

var buf: [100]u8 = undefined; const s: []u8 = buf[20..80]; // 指向 buf 的一个子区间 ``` 底层由一个指向元素起始的指针 + 一个长度组成。

  • 内存布局与所有权
    • 存储位置:指针和长度字段在栈上,数据不归切片所有
    • 所有权:借用,不释放底层内存
    • 对齐:与底层缓冲区一致
  • 操作与语法
    • 索引:s[0]s[s.len-1]
    • 迭代:for (s) |v| …
    • 不可增删,仅视图

1.3 动态数组 std.ArrayList(T)#

  • 定义与底层映射

const std = @import("std"); var list = std.ArrayList(u32).init(std.heap.page_allocator); ``` 底层是一个指针(heap buffer)、当前长度、容量三项。

  • 内存布局与所有权
    • 存储位置:控制块在栈上,内容在堆上
    • 所有权:负责在 deinit() 时释放底层堆内存
    • 对齐:分配器决定
  • 操作与语法
    • 尾部追加:try list.append(x)
    • 随机访问:list.items[i]
    • 弹出末尾:list.pop()
    • 可增删,但中间插入/删除复杂度高

1.4 双端队列 std.DequeList(T)#

  • 定义与底层映射

const std = @import("std"); var dq = std.DequeList(u8).init(std.heap.page_allocator); ``` 底层通常是分块的环形缓冲区。

  • 内存布局与所有权
    • 存储位置:控制结构在栈上,块状数据在堆上
    • 所有权:deinit() 时释放所有块
    • 对齐:分配器决定
  • 操作与语法
    • 头部/尾部入队:dq.pushFront(x), dq.pushBack(x)
    • 头部/尾部出队:dq.popFront(), dq.popBack()
    • 随机访问:dq.items[i]
    • 适合两端高频增删

1.5 SIMD 向量 @Vector(T, N)#

  • 定义与底层映射

const Vec4 = @Vector(f32, 4); ``` 编译期映射为 LLVM <4 x float>,在支持的 CPU 上使用 SSE/AVX 等指令。

  • 内存布局与所有权
    • 存储位置:寄存器或栈
    • 所有权:值类型,整体拷贝
    • 对齐:与架构寄存器宽度一致
  • 操作与语法
    • 并行算术:+ - * /
    • 重排:@shuffle(v, mask)
    • 掩码选取:@select(mask, a, b)
    • 归约:手动 v[0] + v[1] + …(或新版Zig @reduce

2. 五种类型对比表#

特性[N]T[]TArrayList(T)DequeList(T)@Vector(T,N)
长度编译期固定运行时固定运行时可变运行时可变编译期固定
存储栈/全局指针 + 长度堆(内容)+栈(控件)堆(块状数据)+栈(控件)寄存器/栈
所有权值类型借用拥有,需 deinit()拥有,需 deinit()值类型
对齐类型对齐与底层一致分配器决定分配器决定寄存器宽度
增删不支持不支持支持末尾操作支持两端操作不支持
随机访问O(1)O(1)O(1)O(1)O(1)
迭代开销与标量相同与标量相同略高于切片略高于切片与标量相同
典型场景编译期常量、协议头视图/函数参数可变集合、尾部追加双端队列操作并行标量运算

3. 其他语言中的 SIMD 向量对照#

语言/库类型语法示例
C / C++ (intrinsics)__m128 / __m256_mm_add_ps(a, b)
Rust (std::simd)Simd<f32, 4>let c = a + b;
Swift (Apple SIMD)SIMD4<Float>let c = a &+ b
.NET (C# System.Numerics)Vector<float>var c = a + b;
Java Vector APIFloatVectorvar c = a.add(b);
Julia StaticArrays.jlSVector{4, Float32}c = a + b
GLSL / HLSL (Shaders)vec4 / float4vec4 c = a + b;
Python (NumPy ndarray)numpy.ndarrayc = a + b (广播)

现代语言都在尝试“一套代码映射最优指令集”,以提升可移植性与性能。#

4. 场景选型建议#

  • 批量并行标量运算@Vector(T, N)
  • 编译期、定长数据[N]T
  • 借用/视图已有缓冲[]T
  • 动态可变集合(尾部增删多)std.ArrayList(T)
  • 双端高效增删std.DequeList(T) 通过以上分层介绍与对比,你即可根据数据特性内存语义性能需求等维度,灵活选用最合适的 Zig 容器与向量类型。