常见的lisp typecase与defgeneric运行时分析

4 graphics common-lisp generic-programming

我正在编写一个使用opengl的常见lisp的应用程序,随着事情的发展我已经意识到我有一些选择.我有很多不同的类都需要代码来快速和经常地渲染它们,所以我正在考虑以下代码结构:

(defgeneric render (x))
(defmethod render ((x vanilla-foo))
   (generic-foo-stuff)
   (vanilla-specific-stuff)
   (more-generic-foo-stuff))
(defmethod render ((x chocolate-foo))
   (generic-foo-stuff)
   (chocolate-specific-stuff)
   (more-generic-foo-stuff))
Run Code Online (Sandbox Code Playgroud)

等等,很多这些方法.另一种方法是使用typecase语句:

(defun render (any-old-foo)
   (generic-foo-stuff)
   (typecase
      (vanilla-foo 
         (vanilla-specific-stuff))
      (chocolate-foo
         (chocolate-specific-stuff))
      ;;and so on, lots of cases here
    )
    (more-generic-foo-stuff))
Run Code Online (Sandbox Code Playgroud)

我想这些都是以他们自己的方式丑陋,但我的假设是lisp将使用某种哈希表O(1)查找引擎,将传递给泛型函数的参数类型映射到所需方法的位置而第二种方法需要O(n)类型比较才能通过typecase语句.另一方面,根据散列的速度有多慢或多快,在第一种方法真的更快之前,我可能需要成千上万的foo风味.

有一个很好的表现理由我应该喜欢一个吗?我也对其他建议或对某种文件的引用持开放态度,这些文件使我更清楚在每种情况下发生的事情.我也很好奇你可能遇到的这种冲突的其他情况.

谢谢!

Ter*_* D. 6

至少你可以通过将泛型的东西:before:after方法分解出来来使用泛型函数的代码变得不那么难看:

(defgeneric render (x))

(defmethod render :before (x) ; Do what always has to be done first
  (generic-foo-stuff))

(defmethod render :after (x) ;  Do what always has to be done last
  (more-generic-foo-stuff))

(defmethod render ((x vanilla-foo)) ; Do only vanilla-specific things here
   (vanilla-specific-stuff))

(defmethod render ((x chocolate-foo)) 
   (chocolate-specific-stuff))
Run Code Online (Sandbox Code Playgroud)


Rai*_*wig 5

如果有的话,可以使用泛型函数

  • 有各种参数组合的多种实现
  • 想要使函数可扩展
  • 想通过重用片段(方法)来汇编代码

然后我们也可以使用:before:after方法重写你的例子.

如果代码应尽可能快速和静态,那么泛型函数就不是一个好的选择.

如果您需要提前计划性能,那么您最好进行一些实验并测量时间.