我正在编写一个使用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))
等等,很多这些方法。另一种方法是使用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))
我认为这些都是以自己的方式丑陋,但我的假设是lisp将在引擎盖下使用某种哈希表O(1)查找,将传递给泛型函数的参数类型映射到位置所需的方法,而第二种方法将需要O(n)类型比较通过typecase语句。另一方面,根据散列的速度有多慢或多快,在第一种方法真正加快之前,我可能需要数千种foo风味。
有一个很好的表现理由我应该喜欢一个吗?我也对其他建议或对某种文件的引用持开放态度,这些文件使我更清楚在每种情况下发生的事情。我也很好奇你可能遇到的这种冲突的其他情况。
谢谢!
答案 0 :(得分: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))
答案 1 :(得分:5)
如果一个
,可以使用泛型函数然后我们也可以使用:before
和:after
方法重写您的示例。
如果代码应该尽可能快速和静态,那么泛型函数就不是一个好的选择。
如果您需要提前计划性能,那么您最好进行一些实验并测量时间。