如何解决堆栈的写时复制 引用计数不可变对象
如何在大数后缀计算中实现堆栈管理的写时复制技术?
我想针对以下操作优化我的系统:
duplicate top of stack
swap the two top elements
copy the second element on stack to the top
rotate the stack making the third element on top
apply n-ary operations on the stack
一个典型的操作从栈顶取一些参数,并留下一些结果。
我的堆栈被实现为一个数组,其中数据从低内存增长到高内存,指针从高内存增长到低内存。
解决方法
正如我所见,问题不在于写时复制技术本身,而在于内存管理和垃圾收集。
在 Forth 中,我们不能有运算符重载,并且应该为每一类数字明确单独的一组操作。那么我们有两个选择:
-
- 对 bigint 对象(它们的处理程序)进行的一组操作,带有手动内存管理,类似于对文件、动态内存缓冲区或其他对象的操作。
-
- 一整套操作,包括单独的堆栈,例如对浮点数的操作,以及自动内存管理。
请注意,选项 (2) 在幕后包含 (1)。
引用计数
在选项 (2) 中实现自动内存管理的一种方法是使用专用堆栈(或者可能是两个堆栈)和引用计数。堆栈包含对对象(缓冲区)的引用。如果计数器大于 1,则更改数据的操作(如 b::1+
)应复制缓冲区并将引用替换为新的引用(否则数据可以在该位置更改)。
将项目(引用)放入堆栈应增加其计数器,从堆栈中移除应减少其计数器。当计数器变为 0 时,应释放缓冲区。
诸如b::dup
、b::over
之类的操作会增加计数器。 b::swap
不会改变任何计数器。 b::drop
减少计数器(如果计数器为 0,则释放缓冲区)。
将项目从堆栈移动到 bigint 变量不应更改结果中的计数器。但是应该减少变量先前值(如果有)的计数器。
如果命名变量和常量还不够(例如,拥有用户定义的数组),您可能需要在 API 中引入指向 bigint 对象的指针(一种匿名变量)或处理程序。
不可变对象
实现选项 (2) 的另一种方法是使用不可变对象和垃圾收集循环。这种方式我们不需要统计引用,但是需要维护外部指针列表(包括变量)。
这种垃圾收集的一个简单例子可以在彼得苏维埃托夫的 s 表达式的实现中找到:Функциональное программирование на языке Форт(俄语中的“Functional Programming in Forth language”,但它可以很容易翻译{{3} }).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。