【问题标题】:Do languages with meta-linguistic abstraction perform better than those that just use reflection API for that? [closed]具有元语言抽象的语言是否比仅使用反射 API 的语言表现更好? [关闭]
【发布时间】:2010-12-06 07:41:35
【问题描述】:

比如说,如果我有一个 Lisp 程序,它使用 (eval 'sym) 并在其符号表中查找它,它实际上是否比“静态”语言中的 aClass.getField("sym", anInstance) 之类的性能更好?

【问题讨论】:

  • 我无法想象您能够从语言风格之间的整体性能差异中梳理出 WRT 这一特定功能的性能差异。
  • 您想知道“语言运行得更快”还是对功能感兴趣? “表现得更好”是相当含糊的。
  • 当然是速度方面的表现。
  • 您无法比较语言性能,而是它们的实际实现(编译器/解释器)。
  • @fortran:不确定.. 两种方法都明确说明:1)内置语言自省。 2) 反射 API。

标签: c# java reflection lisp eval


【解决方案1】:

一般来说(模数实现问题,例如字节码与本机代码或代码生成质量),具有元语言抽象的语言提供了更多的能力来创建程序,这些程序的性能优于可以在可比时间范围内创建的程序,而缺乏这种抽象的语言则可以创建这些程序。情况是,当您为自己的语言编写实现时,您拥有比基础语言的编译器可以做的更强大的优化的更多信息。实践中有很多这样的例子。

此外,您似乎将反射(作为“开放实现”的特殊情况)和元语言抽象混合在一起。元语言抽象是关于在基础语言之上构建新语言,而反射(或“开放实现”)是将程序的内部结构暴露给程序本身。

在您的特定示例中(当然,模块实现问题,如字节码与本机代码或代码生成质量),(eval 'sym) 可能更快。原因是'sum 是符号对象而不是字符串。评估符号意味着获取其值单元格。所以 eval 只需要做几件事:

  1. 在对象类型(在本例中为符号)上调度(例如,通过使用值标签来遍历跳转表)
  2. 提取符号的值(通过取消引用符号结构)

但 Java 示例还有更多工作要做:

  1. 根据其名称查找字段。这需要例如计算字符串的哈希值并使用哈希表
  2. 提取字段的值(通过在特定于字段的偏移处取消引用实例指针)
  3. 框住值(如果它不是参考)

特别昂贵的部分是计算哈希并遍历哈希表。

【讨论】:

    【解决方案2】:

    这取决于语言的实现。

    绝对没有理由,例如aClass.getField("sym", anInstance) 不应与 eval 完全相同。

    另一方面,即使在实际实现中,速度也有很大不同。例如。在 .Net 中有慢速反射方法和快速反射方法(通常快 100 倍甚至更多)。您需要哪一个在很大程度上取决于您实际想要使用该方法做什么。您只想读取一个值吗?改变一个值?安全相关吗?

    【讨论】:

    • =|我不知道这些问题
    • aClass.getField 可能较慢是有原因的 - 它必须从其名称(字符串)中提取字段元对象。
    【解决方案3】:

    这个问题没有很好地提出,部分原因是这两种方法并不相互排斥。

    例如,Common Lisp 提供了EVAL

    Common Lisp 还提供了许多反射功能,允许您查看包中的符号、按名称查找(全局)变量的值、按名称构造类的实例、查找或设置类中槽的值、或根据名称调用函数。通过广泛实施(尽管非 ANSI 标准)的 CLOS 元对象协议,您可以根据它们的名称找到更多关于类和泛型函数的信息。

    当然,比较语言而不是实现的性能问题仍然存在。自然,已编译为本机代码的 Common Lisp 将与正在解释的 Common Lisp 执行完全不同,并且大多数 CL 实现允许您混合编译和解释代码(尽管少数仅提供编译器)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多