栈机器如何高效存储不同大小的数据类型?现有实现是否合理
栈机器多类型存储的常见实现方案
你当前的固定8字节槽的栈实现是行业内非常常见的方案,并非不合理,两种主流实现的差异和适用场景如下:
1. 定宽栈槽方案(就是你当前在用的实现)
- 实现逻辑:所有入栈数据统一扩展到栈槽的固定宽度(你的场景是8字节),不管原始数据是1字节的byte还是2字节的short,都占用一个完整的栈槽
- 优势:
- 栈顶指针计算极简单,入栈出栈仅需要对top做+1/-1操作,无需额外计算偏移量
- 天然满足内存对齐要求,不会出现跨缓存行、不对齐访问的性能损耗
- 代码实现简单,出错概率极低
- 劣势:小数据存储存在空间浪费
- 适用场景:绝大多数通用虚拟机实现(比如JVM的操作数栈、Lua的栈等都采用类似逻辑),现在内存资源充足,单栈通常最大也就几MB,哪怕每个槽浪费7字节,整体浪费的空间也完全可以忽略,换回来的运行效率收益高很多
2. 变长存储方案
如果你的运行环境内存极受限(比如嵌入式场景,总内存只有几十KB),可以考虑这种方案:
- 实现逻辑:
- 将栈底层改为
unsigned char类型的字节数组,top改为字节偏移量而非槽位索引 - 入栈时根据数据类型长度写入对应字节数,top对应增加对应长度;出栈同理按长度减少top
- 可选优化:如果要避免不对齐访问的性能问题,可以在写入非对齐长度数据时额外补对齐字节,空间开销比定宽槽还是小很多
- 将栈底层改为
- 注意事项:
- 你需要通过指令类型提前知道当前要操作的栈数据长度,比如
push_byte指令默认操作1字节,push_long默认操作8字节,不需要额外存储元数据 - 如果需要支持运行时动态判断类型,需要给每个栈元素加类型标签,会额外占用1-2字节空间,需要权衡收益
- 你需要通过指令类型提前知道当前要操作的栈数据长度,比如
- 优势:空间利用率极高
- 劣势:地址计算复杂,每次操作都需要额外计算偏移量,不对齐访问可能带来性能损耗,实现复杂度高容易出bug
补充一个你的代码小问题:你当前的get()函数返回的是top-1(栈顶的槽位索引),不是栈顶存储的元素值,正确实现应该是return stack[top-1];,如果这不是笔误的话可以调整下。
内容的提问来源于stack exchange,提问作者PugsAreCute
相关产品推荐
相关产品推荐

