说,如果我有一个Lisp程序,它使用(eval 'sym)
并在其符号表中查找它实际上比“静态”语言中的aClass.getField("sym", anInstance)
更好吗?
答案 0 :(得分:2)
这取决于语言的实现。
绝对没有理由,例如aClass.getField(“sym”,anInstance)不应该与eval完全相同。
另一方面,即使在实际实施中,速度也大不相同。例如。在.Net中有慢速反射方法和快速反射方法(通常是100倍甚至更快)。您需要哪一个在很大程度上取决于您实际想要使用该方法做什么。你想读一个值吗?改变一个值?安全性是否相关?
答案 1 :(得分:2)
问题没有得到很好的解决,部分原因是这两种方法并不相互排斥。
就像一个例子,Common Lisp提供EVAL
。
Common Lisp还提供了许多反射功能,允许您查看包中的符号,按名称查找(全局)变量的值,按名称构造类的实例,查找或设置类中的槽的值,或根据他们的名字来调用函数。通过广泛实现(尽管非ANSI标准)CLOS元对象协议,您可以根据名称找到更多关于类和泛型函数的信息。
当然,比较语言的性能而不是实现的问题仍然存在。自然编译为本机代码的Common Lisp与正在解释的Common Lisp的执行方式完全不同,大多数CL实现允许您混合编译代码和解释代码(尽管少数只提供编译器)。
答案 2 :(得分:2)
一般而言(模块化实现问题,如字节码与本机代码或代码生成质量),具有金属语言抽象的语言提供了更强大的功能来创建程序,这些程序的性能优于可在类似时间范围内使用缺少此类抽象的语言创建的程序。这种情况是,当您为自己的语言编写实现时,您可以获得更多信息来进行比基本语言编译器更强大的优化。实践中有很多例子。
此外,您似乎将反射(是“开放实现”的特定情况)和金属语言抽象混合在一起。元语言抽象是关于在基础语言之上构建新语言而反思(或“开放实现”)是关于将程序内部暴露给程序本身。
在您的特定示例中(当然,模块实现问题,如字节码与本机代码或代码生成质量),(eval 'sym)
可能更快。原因是'sum
是符号对象而不是字符串。评估符号意味着获取其价值单元格。因此,eval只需做几件事:
但Java示例还有更多事情要做:
特别昂贵的部分是计算哈希并通过哈希表。