微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Common Lisp:在不使用 &rest 参数的情况下高效地处理提供的 p 参数

如何解决Common Lisp:在不使用 &rest 参数的情况下高效地处理提供的 p 参数

假设我有这个功能

(defun bar (a &optional (b nil bp))
  (declare (ignore a b bp)) ; <-- replace it with (list a b bp)
                            ;     to check for correctness
  )
;; I want to preserve the value of bp here inside bar,and inside foo below

并且我希望围绕 bar 编写一个包装器:

(defun foo (a &optional (b nil bp))
  (declare (optimize speed))
  (apply #'bar a (nconc (when bp (list b)))))

同时在从 bpfoo调用中保留 bar 的值,并且还保持参数 b 在 emacs 的 minibuffer / eldoc-mode 中可见。我想知道是否有一种可能不可移植的非 consing 方法来保留此调用bp 的值。

例如

CL-USER> (time (loop repeat 1000000 do (foo 4 2)))
Evaluation took:
  0.040 seconds of real time
  0.043656 seconds of total run time (0.043656 user,0.000000 system)
  110.00% cpu
  96,380,086 processor cycles
  15,990,784 bytes consed <--- plenty of consing
  
NIL

如果我忽略 b-visibility-in-eldoc,我可能会使用 &rest 参数,但我确实希望参数可见。

虽然在这种特殊情况下还有其他方法可以实现这一点,但我确实想考虑存在多个 &optional(或 &keyword)参数的情况。

解决方法

使用 cond 表单来决定如何调用 bar

(defun bar (a &optional (b nil bp) (c nil cp))
  (declare (ignore a b bp c cp)))

(defun foo (a &optional (b nil bp) (c nil cp))
  (declare (optimize speed))
  (cond (cp (funcall #'bar a b c))
        (bp (funcall #'bar a b))
        (t (funcall #'bar a))))
CL-USER> (time (loop repeat 1000000 do (foo 1 2 3)))
Evaluation took:
  0.015 seconds of real time
  0.017203 seconds of total run time (0.017148 user,0.000055 system)
  113.33% CPU
  41,186,554 processor cycles
  0 bytes consed

检查传递给 bar 的参数:

(defun bar (a &optional (b nil bp) (c nil cp))
  (list a b bp c cp))
CL-USER> (foo 1 2 3)
(1 2 T 3 T)
CL-USER> (foo 1 2)
(1 2 T NIL NIL)
CL-USER> (foo 1)
(1 NIL NIL NIL NIL)
,

我不确定 barfoo 实际上应该做什么,但是呢:

(defun foo (a &optional (b nil bp))
  (declare (optimize speed))
  (funcall #'bar a (when bp b))) 

CL-USER> (time (loop repeat 1000000 do (foo 4 2)))
Evaluation took:
  0.005 seconds of real time
  0.005810 seconds of total run time (0.005804 user,0.000006 system)
  120.00% CPU
  8,099,624 processor cycles
  0 bytes consed

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。