Common lisp 如何在公共Lisp中内联函数

Common lisp 如何在公共Lisp中内联函数,common-lisp,inline,Common Lisp,Inline,有人能告诉我如何在CommonLisp中内联函数吗? 我有很多小函数,它们总是被调用,所以节省这些函数调用的成本是很好的 例如,如何在“调用者”函数中内联“独立”函数 (defun standalone () (* 2 5)) (defun caller () (standalone)) 文件是 (但请记住,定义一个总是返回数字文本10的函数没有多大意义…请参阅食谱: 如果编译器支持,内联声明将用函数体替换函数调用。它将节省函数调用的成本,但可能会增加代码大小。使用内联函数的最佳情况可能

有人能告诉我如何在CommonLisp中内联函数吗? 我有很多小函数,它们总是被调用,所以节省这些函数调用的成本是很好的

例如,如何在“调用者”函数中内联“独立”函数

(defun standalone ()
 (* 2 5))

(defun caller ()
 (standalone))
文件是

(但请记住,定义一个总是返回数字文本10的函数没有多大意义…

请参阅食谱:

如果编译器支持,内联声明将用函数体替换函数调用。它将节省函数调用的成本,但可能会增加代码大小。使用内联函数的最佳情况可能是那些小但常用的函数。下面的代码片段展示了如何鼓励和禁止内联代码

;; The globally defined function DISPATCH should be open-coded,
;; if the implementation supports inlining, unless a NOTINLINE 
;; declaration overrides this effect.
(declaim (inline dispatch))
(defun dispatch (x) (funcall (get (car x) 'dispatch) x))

;; Here is an example where inlining would be encouraged.
;; Because function DISPATCH was defined as INLINE, the code 
;; inlining will be encouraged by default.
(defun use-dispatch-inline-by-default () 
  (dispatch (read-command)))

;; Here is an example where inlining would be prohibited.
;; The NOTINLINE here only affects this function.
(defun use-dispatch-with-declare-notinline  ()
  (declare (notinline dispatch))
  (dispatch (read-command)))

;; Here is an example where inlining would be prohibited.
;; The NOTINLINE here affects all following code.
(declaim (notinline dispatch))
(defun use-dispatch-with-declaim-noinline () 
  (dispatch (read-command)))

;; Inlining would be encouraged becuase you specified it.
;; The INLINE here only affects this function.
(defun use-dispatch-with-inline () 
  (declare (inline dispatch))
  (dispatch (read-command)))


一些实现,如Allegro CL编译器


define compiler macro
(不同于
defmacro
)创建的宏也可以用于内联代码。

非常感谢,它很有效。实际上,“独立”函数没有任何意义,但我想知道函数调用的成本,我发现“独立”需要0.42秒,而“调用方”需要0.61秒(执行100000000次)。因此,添加的函数调用似乎消耗了“独立”函数总成本的50%。我不知道与其他语言相比,这种成本有多高,但我还是觉得它非常昂贵,值得担心。正如Ehvince在他的回答中指出的,内联与否是代码大小和执行时间之间的权衡。所有语言的调用机制都是类似的:在堆栈上推送返回地址、所有要更改的寄存器的值以及参数值,进行调用,将参数从堆栈中弹出;然后,在子例程调用结束时,恢复寄存器和返回地址,恢复堆栈并从那里恢复执行。有许多可能的复杂性(例如返回值的处理方式),但是,是的,函数调用是昂贵的。不可读的代码更是如此……感谢您提供了这个很棒的资源:)很有趣。不熟悉Allegro CL.“用户定义的函数从不内联编译。”这对于商业产品来说很奇怪。不相信他们的理由。你需要的是一个变量,而不是一个函数!
;; The globally defined function DISPATCH should be open-coded,
;; if the implementation supports inlining, unless a NOTINLINE 
;; declaration overrides this effect.
(declaim (inline dispatch))
(defun dispatch (x) (funcall (get (car x) 'dispatch) x))

;; Here is an example where inlining would be encouraged.
;; Because function DISPATCH was defined as INLINE, the code 
;; inlining will be encouraged by default.
(defun use-dispatch-inline-by-default () 
  (dispatch (read-command)))

;; Here is an example where inlining would be prohibited.
;; The NOTINLINE here only affects this function.
(defun use-dispatch-with-declare-notinline  ()
  (declare (notinline dispatch))
  (dispatch (read-command)))

;; Here is an example where inlining would be prohibited.
;; The NOTINLINE here affects all following code.
(declaim (notinline dispatch))
(defun use-dispatch-with-declaim-noinline () 
  (dispatch (read-command)))

;; Inlining would be encouraged becuase you specified it.
;; The INLINE here only affects this function.
(defun use-dispatch-with-inline () 
  (declare (inline dispatch))
  (dispatch (read-command)))