【问题标题】:Common lisp typecase vs defgeneric runtime analysisCommon lisp typecase vs defgeneric 运行时分析
【发布时间】:2015-05-31 18:28:44
【问题描述】:

我正在编写一个使用 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 风味才能真正更快地第一种方法。

是否有一个很好的性能理由让我更喜欢其中一个?我也愿意接受其他建议或对某种文件的引用,这些文件让我更清楚每种情况下的幕后情况。我也很好奇您可能遇到过的此类冲突的其他实例。

谢谢!

【问题讨论】:

标签: graphics common-lisp generic-programming


【解决方案1】:

至少您可以通过将泛型内容分解为: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))

【讨论】:

    【解决方案2】:

    如果一个人会使用泛型函数

    • 具有多种参数组合的多种实现方式
    • 想让函数可扩展
    • 希望通过重用片段来组装代码(方法

    那我们不妨用:before:aftermethods 重写你的例子。

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

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

    【讨论】:

      猜你喜欢
      • 2011-01-10
      • 2020-09-18
      • 2023-03-25
      • 2015-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多