unicstl/doc
wjf-hs 0236e6e315 feat(rawbuf): 新增 rawbuf 模块,做随机访问,支持malloc和静态内存。
(之前我突然对darray理解错了,现在的darray设计就是合理的。注意区分开rawbuf和darray)
2026-05-15 15:53:11 +08:00
..
log.md segarray调试期间,发现我的darray设计的非常不合理,size基于insert,而set有基于size。这样新建的darray不能立刻使用set 2026-05-15 13:37:45 +08:00
notes.md feat(rawbuf): 新增 rawbuf 模块,做随机访问,支持malloc和静态内存。 2026-05-15 15:53:11 +08:00
PERF.md feat(perf): 重构性能测试框架(支持多组参数配置)并增加perf_log(利用darray实现并格式化输出) 2026-05-13 17:00:39 +08:00
README.md refactor(queue):底层修改为deque 2026-05-14 18:29:12 +08:00
unicstl.log rbt测试通过 2024-09-02 21:14:16 +08:00

unicstl

编译环境

  • 编译器gcc 13.2.0
  • 标准:--std=c99

特点

原理 优势 弊端
链表 插入删除效率高 有额外指针开销
动态数组 随机访问效率高 扩容时数据搬移代价较大
--- --- ---
单链表 适用内存受限场景 逆向不便
双向链表 频繁双向遍历的场景(如光标移动) 空间开销大

性能比较

数据结构 < > <空间复杂度>
--- ( ) ( ) 最坏
--- 访问 搜索 插入 删除 访问 搜索 插入 删除 ---
数组 O(1) O(n) O(n) O(n) O(1) O(n) O(n) O(n) O(n)
O(n) O(n) O(1) O(1) O(n) O(n) O(1) O(1) O(n)
队列 O(n) O(n) O(1) O(1) O(n) O(n) O(1) O(1) O(n)
单向链表 O(n) O(n) O(1) O(1) O(n) O(n) O(1) O(1) O(n)
双向链表 O(n) O(n) O(1) O(1) O(n) O(n) O(1) O(1) O(n)
跳表 O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(n) O(n) O(n) O(n) O(n*log(n))
哈希表 N/A O(1) O(1) O(1) N/A O(n) O(n) O(n) O(n)
二叉搜索树 O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(n) O(n) O(n) O(n) O(n)
AVL树 O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(n)
红黑树 O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(n)
B树 O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(log(n)) O(n)

【答疑】 若链表的操作流程为,先查找元素再删除元素。那么时间复杂度确实是$O(n)$。但是链表的增删优势,在其他应用有体现。比如双向队列,插入和删除效率都为$O(1)$。

规范

版本说明

命名 版本说明 范围 更新说明
VERSION_MAJOR 主版本号 0 ~ 99 代码框架大改,完全不兼容旧版
VERSION_MINOR 次版本号 0 ~ 99 代码框架尽量兼容旧版增信大功能、修复重大bug等
VERSION_MICRO 小版本号 0 ~ 99 代码框架兼容旧版新增小功能、修复bug等

举例说明:

// 若 major > 0 ,则代表正式发布版本
#define UNICSTL_VERSION_MAJOR    1
#define UNICSTL_VERSION_MINOR    2
#define UNICSTL_VERSION_MICRO    5
#define UNICSTL_VERSION          ((UNICSTL_VERSION_MAJOR << 16) | (UNICSTL_VERSION_MINOR << 8) | UNICSTL_VERSION_MICRO)

工程命名

工程名(_功能)_v版本号_日期(_时间)(-其他信息)

括号内表示可选项

其他信息后缀 说明 详细
aX alpha内测版 可能仅测试了新增功能,但没有测试新增功能对其他模块的影响
bX beta公测版 不仅测试了新增功能,也测试了其他模块,尽量保证新增的功能不影响原来的旧功能。
... 或者添加其他有有效信息

举例说明:

unicstl_stack_v1.2.5_20240717-a0.zip

# 带a或者b后缀表示当前版本发布前的测试版。如果发布后则直接更新版本号了

deque实现对比

segarray类比c++的dequeringbuf类比rust的VecDeque

若capacity足够不需要扩容

场景 ringbuf segarray 说明
size < capacity/2 无扩容 无扩容 性能一样
size > capacity/2 无扩容 内部预留耗尽,触发段/map分配 ringBuf连续内存缓存更优segarray因中段起始预留不库容容量折半

若capacity不够需要扩容

  1. capacity 合理的情况下(初值预估可能大小)
场景 ringbuf segarray 说明
objsize 很大 按倍数扩整体连续大内存 + 全量数据搬移 新分配小段、无旧数据拷贝顶多map指针数组扩容 segarray 碾压,规避巨型对象整体拷贝开销
objsize 很小 倍数扩容开销极低,连续内存缓存友好 逐段分配、map偶尔扩容间接寻址拖累缓存 ringBuf占优小对象拷贝成本可忽略连续内存优势拉满

备注C++标准库 deque 靠固定 512 字节自适应每段元素数。也即可以让segarray 借助 objsize 和 512 对比,来实现方案优化

  1. capacity 非常小情况
场景 ringbuf segarray 说明
objsize 很大 每次翻倍扩连续巨块内存 + 大批量搬移大对象 每次只按需分配单个,少量段,永远不拷贝旧数据 segarray 依然优势明显
objsize 很小 指数倍数扩容,扩容次数少、成本低 退化成「类链表模式」:每插易新建段 + 频繁小分配,虽支持随机访问,但内存碎片化、分配次数暴增 ringBuf 完胜,翻倍扩容策略吊打退化的 SegArray