在C等低级语言中实现Lisp的缺点/对的有哪些选择?
一个常见的实现是由字段类型,汽车和 cdr 组成的结构。我知道链接列表对于存储效率不是很高,但是额外的类型字段会使其更糟糕。
我在维基百科上读到,Lisp machines曾用于为每个单词添加额外的位以获取类型信息。但今天的架构有哪些选择(x86,ARM)?
答案 0 :(得分:3)
缺点单元格只是我们需要在Lisp中表示的一种数据。其他的是数组或向量。字符串。字符。数字。符号。记录。类的实例。
不仅Lisp Machines使用了标记位。大多数Lisp实现都使用它们。
大多数Lisp实现只使用每个内存字中的位。各种Lisp机器每个字的位数不同。 Symbolics 36 **机器使用36位字。 Symbolics Ivory使用40位字。 TI Explorer使用32位字。因此,Symbolics使用了不常见的字大小,TI使用了正常字大小。 Symbolics能够通过40位CPU(16 GB)解决更多内存问题。一个单词的8位用于标签。 Symbolics在表示数据时也有各种其他优化(例如列表可以表示为 cdr编码的向量 - 这种技术在当前的Lisp实现中不使用)。
今天的大多数CPU都是32位或64位架构。这使得一个Lisp cons单元的大小就是这些单词中的两个,并且这些位必须适合这些单词大小。 fixnum小于32位或64位。 fixnum是一个整数,它适合单词减去标记位。对于较大的整数,数字需要以不同的方式表示。因此,完整的64位长数字不能代表64位机器上的fixnum。 Common Lisp提供有关这些大小的信息。在我的64位LispWorks上,最积极的解决方案是1152921504606846975。
CL-USER > MOST-POSITIVE-FIXNUM
1152921504606846975
为标记位浪费额外的内存是不常见的。大多数当前的Lisp实现必须将标记位放入数据字(32位或64位)。 Lisp实现者一直在努力使其尽可能高效。
答案 1 :(得分:2)
您可以使用指针中的标记替换type
字段。
结合NaN boxing,您可以将每个堆叠广告位(以及car
结构的cdr
和cons
字段)缩减为double
的大小
然而,每个cons单元仍然会有malloc
开销(一个或两个单词)。