stage2 提供近乎完整的功能但出现严重性能问题 添加stage0的原生性能记录 stage1添加更多内置函数 nob重构代码使其更加健壮

This commit is contained in:
zzy committed 2026-09-19 18:08:43 +08:00
1 parent b5a7a811b3
commit e02b0c633a
35 files changed
+14018 -216

No files matched your search

+39 -12
View File
@@ -49,14 +49,17 @@ fn new(elem_size: usize, elem_align: usize): VecResult {
ret .Ok(blank(elem_size, elem_align));
}
fn valid(self: Vec): bool {
if self.elem_size == 0 || !valid_alignment(self.elem_align) { ret false; }
// 按指针接收,避免每次调用复制整个 Vec;内联对齐检查,省一次函数调用。
fn valid(self: *Vec): bool {
if self.elem_size == 0 { ret false; }
var a = self.elem_align;
if a == 0 || (a & (a - 1)) != 0 { ret false; }
if self.len > self.cap { ret false; }
if self.cap == 0 {
ret self.raw == null && self.data == null && self.len == 0;
}
if self.raw == null || self.data == null { ret false; }
ret (self.data as usize & (self.elem_align - 1)) == 0;
ret (self.data as usize & (a - 1)) == 0;
}
fn status_error(kind: Kind): Status {
@@ -108,9 +111,8 @@ fn allocate(capacity: usize, elem_size: usize, elem_align: usize): VecResult {
});
}
// 保证至少可容纳 need 个元素。所有检查在原对象改变前完成。
fn reserve(self: *Vec, need: usize): Status {
if !valid(self.*) { ret status_error(.InvalidArgument); }
// 与 reserve 相同,但假定调用方已校验 self(内部热路径用,省去重复 valid)。
fn reserve_raw(self: *Vec, need: usize): Status {
if need <= self.cap { ret .Ok; }
var new_cap = grow_capacity(self.cap, 8, need);
@@ -140,14 +142,25 @@ fn reserve(self: *Vec, need: usize): Status {
ret .Ok;
}
// 保证至少可容纳 need 个元素(外部入口,含校验)。
fn reserve(self: *Vec, need: usize): Status {
if !valid(self) { ret status_error(.InvalidArgument); }
ret reserve_raw(self, need);
}
// 预分配恰好 capacity 个元素(等价“with_capacity”)。
fn with_capacity(elem_size: usize, elem_align: usize, capacity: usize): VecResult {
ret allocate(capacity, elem_size, elem_align);
}
fn get(self: *Vec, index: usize): PtrResult {
if !valid(self.*) { ret .Err(Error.make(.InvalidArgument)); }
if !valid(self) { ret .Err(Error.make(.InvalidArgument)); }
if index >= self.len { ret .Err(Error.make(.OutOfRange)); }
ret .Ok(self.data + index * self.elem_size);
}
fn set(self: *Vec, index: usize, elem: *u8): Status {
if !valid(self.*) || elem == null { ret status_error(.InvalidArgument); }
if !valid(self) || elem == null { ret status_error(.InvalidArgument); }
if index >= self.len { ret status_error(.OutOfRange); }
var dst = self.data + index * self.elem_size;
ret move(dst[0..self.elem_size], elem[0..self.elem_size]);
@@ -155,7 +168,7 @@ fn set(self: *Vec, index: usize, elem: *u8): Status {
// 追加 count 个连续元素。elems 可以指向 self 当前已初始化的元素区。
fn append(self: *Vec, elems: *u8, count: usize): Status {
if !valid(self.*) { ret status_error(.InvalidArgument); }
if !valid(self) { ret status_error(.InvalidArgument); }
if count == 0 { ret .Ok; }
if elems == null { ret status_error(.InvalidArgument); }
@@ -190,7 +203,7 @@ fn append(self: *Vec, elems: *u8, count: usize): Status {
}
}
match reserve(self, new_len) {
match reserve_raw(self, new_len) {
.Ok => {},
.Err(error) => { ret .Err(error); },
}
@@ -209,9 +222,23 @@ fn push(self: *Vec, elem: *u8): Status {
ret append(self, elem, 1);
}
// 热路径:假定 self 有效且已有容量时直接写入;容量不足才回退到 append。
fn push_raw(self: *Vec, elem: *u8): bool {
if self.len < self.cap {
copy(self.data + self.len * self.elem_size, elem, self.elem_size);
self.len = self.len + 1;
ret true;
}
match append(self, elem, 1) {
.Ok => { ret true; },
.Err(error) => { ret false; },
}
ret false;
}
// 将末元素复制到 out,然后缩短数组。out 可以与元素区重叠。
fn pop(self: *Vec, out: *u8): Status {
if !valid(self.*) || out == null { ret status_error(.InvalidArgument); }
if !valid(self) || out == null { ret status_error(.InvalidArgument); }
if self.len == 0 { ret status_error(.OutOfRange); }
var source = self.data + (self.len - 1) * self.elem_size;
match move(out[0..self.elem_size], source[0..self.elem_size]) {
@@ -229,7 +256,7 @@ fn clear(self: *Vec) {
// 成功时先释放 out 原有存储再提交副本;失败保持 out 不变。
// out 与 src 指向同一个 Vec 也允许。
fn clone(out: *Vec, src: Vec): Status {
if !valid(out.*) || !valid(src) { ret status_error(.InvalidArgument); }
if !valid(out) || !valid(&src) { ret status_error(.InvalidArgument); }
if out.elem_size != src.elem_size || out.elem_align != src.elem_align {
ret status_error(.InvalidArgument);
}