Noo*_*oob 2 character common-lisp cons output
我正在为LISP中的一种语言编写一个编译器,总体目标是让编译器从原始语言生成LISP代码.试图测量生成的代码的性能,我发现它严重缺乏打印字符串.
在原始语言中,字符是字节算术值,因此字符串是字节数组,字节的值对应于其值为字节的ascii代码的字符."可打印"字节数组必须以空值终止.因此,要将字节数组作为字符串打印,我必须在打印之前将原始数组的元素映射到字符中.处理此问题的函数如下:
(defun writeString (X &AUX (NPOS 0) (i 0))
(declare (type (simple-VECTOR fixnum *) x))
(declare (type fixnum NPOS i))
(SETF NPOS (POSITION 0 X))
(IF (NOT NPOS)
(SETF NPOS (LENGTH X)))
(princ (MAKE-ARRAY NPOS
:INITIAL-CONTENTS (map 'vector
#'code-char
(SUBSEQ X 0 NPOS))
:ELEMENT-TYPE 'base-char)))
Run Code Online (Sandbox Code Playgroud)
并将其注入生成的代码中.
运行示例代码时time
,我发现该princ
部件在执行期间导致大量耗费,这会减慢速度.当放置make-array...
静态字符串时,没有减速并且没有消耗,所以我猜这是损坏的部分.
在编译时,我已经在速度上设置了标志,现在在生成的代码中将字节值声明为fixnum.
任何人都可以指出我更好的方法来打印我的字节数组作为字符串,同时避免过多的消耗吗?
我可以将字节存储为get-go中的字符,但这会导致语言的部分因为需要转换而将它们视为数字较慢.
代码中的问题
你的代码:
(defun writeString (X &AUX (NPOS 0) (i 0))
(declare (type (simple-VECTOR fixnum *) x))
(declare (type fixnum NPOS i))
(SETF NPOS (POSITION 0 X))
(IF (NOT NPOS)
(SETF NPOS (LENGTH X)))
(princ (MAKE-ARRAY NPOS
:INITIAL-CONTENTS (map 'vector
#'code-char
(SUBSEQ X 0 NPOS))
:ELEMENT-TYPE 'base-char)))
Run Code Online (Sandbox Code Playgroud)
代码中有几个错误:
i
未使用有一堆编程错误:
简单的解决方案:
(defun writestring (bytestring)
(loop for byte across bytestring
while (plusp byte)
do (write-char (code-char byte))))
Run Code Online (Sandbox Code Playgroud)
声明的类型可以是:
(defun writestring (bytestring)
(declare (vector bytestring))
(loop for byte of-type (integer 0 255) across bytestring
while (plusp byte)
do (write-char (code-char byte))))
Run Code Online (Sandbox Code Playgroud)
相反,(integer 0 255)
人们也可以使用(unsigned-byte 8)
.
关于生成向量:
让我们看看你是如何尝试创建数组的:
使用另一个数组中的内容创建一个包含make-array的数组.为什么不告诉MAP生成正确的数组?
CL-USER 46 > (map '(vector base-char) #'code-char #(102 111 111 98 97 114))
"foobar"
Run Code Online (Sandbox Code Playgroud)
现在,如果您想出于某种原因分配数组:
map-into
了点.它将以较短的序列停止.例:
CL-USER 48 > (let ((bytestring #(102 111 111 98 97 114 0 100 100 100)))
(map-into (make-array (or (position 0 bytestring)
(length bytestring))
:element-type 'base-char)
#'code-char
bytestring))
"foobar"
Run Code Online (Sandbox Code Playgroud)