- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在其他 SO 答案中找到了一些技巧,但显然我无法说服 SBCL 进行内联 fixnum 算术:
(declaim (optimize (speed 2) (safety 1)))
(declaim (ftype (function (fixnum fixnum) double-float) fixnumtest) (inline fixnumtest))
(defun fixnumtest (i j)
(declare (type fixnum i j))
(let* ((n (the fixnum (+ i j)))
(n+1 (the fixnum (1+ n))))
(declare (type fixnum n n+1))
(/ 1.0d0 (the fixnum (* n n+1)) )
)
)
(defun main ()
(format t "~11,9F~%" (fixnumtest 2 3))
)
:results in forced to do GENERIC-* (cost 30)
我还应该尝试什么?
$ sbcl --eval '(load (compile-file "play.lisp"))'
This is SBCL 1.5.1,
…
; compiling file "/opt/tmp/play.lisp" (written 16 OCT 2019 08:03:15 PM):
; compiling (DECLAIM (OPTIMIZE # ...))
; compiling (DECLAIM (FTYPE # ...) ...)
; compiling (DEFUN FIXNUMTEST ...)
; file: /opt/tmp/play.lisp
; in: DEFUN FIXNUMTEST
; (* N N+1)
;
; note: forced to do GENERIC-* (cost 30)
; unable to do inline fixnum arithmetic (cost 4) because:
; The result is a (VALUES
; (INTEGER -21267647932558653961849226946058125312
; 21267647932558653961849226946058125312)
; &OPTIONAL), not a (VALUES FIXNUM &REST T).
; unable to do inline (signed-byte 64) arithmetic (cost 5) because:
; The result is a (VALUES
; (INTEGER -21267647932558653961849226946058125312
; 21267647932558653961849226946058125312)
; &OPTIONAL), not a (VALUES (SIGNED-BYTE 64) &REST T).
; etc.
此外,我是否认为将 float 强制转换为指针(成本 13)
是从函数返回 float 的普通结果?
; (DEFUN FIXNUMTEST (I J)
; (DECLARE (TYPE FIXNUM I J))
; (LET* ((N (THE FIXNUM #)) (N+1 (THE FIXNUM #)))
; (DECLARE (TYPE FIXNUM N N+1))
; (/ 1.0d0 (THE FIXNUM (* N N+1)))))
; --> PROGN SB-IMPL::%DEFUN SB-IMPL::%DEFUN SB-INT:NAMED-LAMBDA
; ==>
; #'(SB-INT:NAMED-LAMBDA FIXNUMTEST
; (I J)
; (DECLARE (SB-C::TOP-LEVEL-FORM))
; (DECLARE (TYPE FIXNUM I J))
; (BLOCK FIXNUMTEST
; (LET* ((N #) (N+1 #))
; (DECLARE (TYPE FIXNUM N N+1))
; (/ 1.0d0 (THE FIXNUM #)))))
;
; note: doing float to pointer coercion (cost 13) to "<return value>"
最佳答案
好吧,编译器正在告诉你答案,也许是以一种有点无用的方式。如果你有两个 fixnums 那么情况就不是这样,例如,将它们相加会得到一个 fixnum:类型 fixnum
在算术运算下不闭合(甚至在 +
下也不闭合) >、-
和 *
,忽略 /
)。
来自SBCL manual :
The SBCL compiler treats type declarations differently from most other Lisp compilers. Under default compilation policy the compiler doesn’t blindly believe type declarations, but considers them assertions about the program that should be checked: all type declarations that have not been proven to always hold are asserted at runtime.
如果你想编译机器算法,你需要做的是告诉编译器它正在使用的类型足够好,它可以知道结果类型足够好,可以立即表示它们。
鉴于您在函数中的算法,并假设一个 64 位实现,那么一个好的类型是 (signed-byte 31)
:使用 (signed-byte 32)
但这失败了,因为你最终得到的东西比 (signed-byte 64)
大。
所以除了在返回时使用最后的双 float 之外,这段代码不会发出警告:
(deftype smallish-integer (&optional (bits 31))
`(signed-byte ,bits))
(declaim (ftype (function (smallish-integer smallish-integer) double-float)
fixnumtest)
(inline fixnumtest))
(defun fixnumtest (i j)
(declare (optimize (speed 2)))
(declare (type smallish-integer i j))
(let* ((n (+ i j))
(n+1 (1+ n)))
(/ 1.0d0 (* n n+1))))
值得注意的是 (signed-byte 64)
比 fixnum
大很多:这没关系,因为在一个函数中编译器可以处理适合寄存器的数字,即使它们大于 fixnums。
我对 x64 汇编器不够熟悉,无法检查所有算术是否都编译为机器指令,但看起来确实如此。
有可能说服 SBCL 编译器您不关心获得正确答案并且它应该只执行机器算术,即使它知道它可能会溢出。我不知道该怎么做。
关于optimization - 如何说服 Lisp SBCL 进行内联 fixnum 运算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58424422/
在 SBCL 上编译 ACL2 时如何避免低级调试器崩溃?这是我在 Linux 上使用 SBCL 1.2.3 编译时收到的错误消息: ACL2 loading '((COMP-FN :EXEC NI
我一直在尝试为 CFFI 绑定(bind) (https://gitorious.org/dh-misc/hdf5/source/cb616fd619a387e3cdc927994b9ad12b6b5
我正在使用 SBCL 转储用 CL 编写的新解释器,并且需要确定二进制文件(可执行 sbcl 转储)的位置以设置一些搜索路径。有没有办法找出方法?我试过 *core-pathname* 但它似乎没有在
我是 lisp 编程的新手。我正在使用 sbcl。在程序线程的一部分中创建为- (sb-thread:make-thread (lambda () (progn (sleep
sbcl 中位向量使用多少内存? 每一位是否花费 1 位内存? 每个位是否花费 1 个字节的内存? 每比特花费 1 个字的内存吗? 最佳答案 SBCL 中的位向量以每位一位有效存储,加上每个向量的一些
我需要分析一个“慢”的函数,即需要非常很长时间才能终止(如果有的话)。在我看来,仍然可以使用 SBCL 中的统计分析器来分析此函数,因为它只是定期采样。然而,当我运行时 (sb-sprof:with-
亲爱的 StackExchange 成员(member), 我最近开始研究 Common Lisp 并想创建一个 Web 界面来管理一个模组化的 Minecraft 服务器。我已经试过了 this s
我正在使用 SBCL 的统计分析器来分析这些函数: (defun fact-rec (n) (if (zerop n) 1 (* n (fact-rec (1- n))))
我想使用 bashcript 将一个字符串作为单个参数传递给 sbcl,但 sbcl 将该字符串拆分为一个列表。 脚本 #!/bin/bash sbcl --noinform --eval "
如何为所有功能设置优化选项,如“speed 3”? (declaim (optimize (speed 3) (debug 0) (safety 0)) 没用( 最佳答案 %> cat test.li
在 sbcl 中, *(sb-mop:class-precedence-list (find-class 'cons)) ==>(# # # #) cons 继承自 list 而不是相反,这不是很奇
我想使用适用于 Windows x86_64 的 SBCL 1.3.3 在 Lisp 中编写斐波那契数计算函数 fib。使用惰性计算来避免重复。到目前为止的工作代码是: (defvar *fibs*
首先,我被迫使用 LispWorks,我想知道它实际使用的是什么编译器,以及我是否可以在 CLI 中使用它。同样在 LispWorks 中,有 defsystem 等方法,它们是以某种方式构建在环境中
如何在开始时禁用包锁定? 我试图将 (sb-ext:disable-package-locks sb-alien) 放在 .sbclrc, 但是,它似乎不起作用。 最佳答案 sb-ext:disabl
考虑这个简单的例子: (deftype image nil '(simple-array single-float (100))) 这里我们定义了一个类型的简写,它是一个包含单个 float 的数组。
众所周知,Maxima 基于普通的 lisp。我正在编写一个在 Maxima 中工作的 lisp 程序;使用 Maxima 程序。我按下参数“maxima -p foo.lisp”来加载 lisp 文
我正在尝试为 SBCL 中实现的订单统计函数计时.谷歌搜索我发现了这个计时功能:(时间形式)。但是我不确定它会返回什么。这似乎是一个很大的数字,但我找不到指定返回值是毫秒、纳秒、系统时间等的文档。 有
我编写了一个服务器,用于生成新线程。其中一些线程需要写入标准输出,但当它们写入时,终端中不会显示任何内容。 sbcl 中是否有某种类型的消息传递 api 允许我将消息发送回主线程? 非常感谢! 最佳答
我试图弄清楚如何在使用 break 之类的东西调用调试器后单步执行 sbcl 和 Slime 中的代码。我不想从头开始。例如,如果我有以下代码: (defun fib (n) (when (eql
函数: 给定一个列表 lst 返回列表内容的所有排列恰好长度为 k,如果没有提供则默认为列表的长度。 (defun permute (lst &optional (k (length lst)))
我是一名优秀的程序员,十分优秀!