阅读caml-list上的一些旧帖子我发现雅克·加里格斯的以下帖子:http://caml.inria.fr/pub/ml-archives/caml-list/2007/11/24e8215c8d844b05db58ed3f79c9645f.en.html
我关心的引用如下:
对任意对象的方法调用可能很慢。这是因为,由于 子类型,在某些情况下没有办法知道方法在哪里 将在表格中,并且必须进行二分搜索。
任何人都可以解释为什么会这样吗?为什么确切的子类型(在这种情况下我假设继承)会影响这个?这是OCaml实现的情况还是其他语言也受此影响?
请指出有关此问题的进一步资源,谷歌让我失望。
答案 0 :(得分:10)
我认为delnan的评论是,在OCaml中,“Subtyping!= inheritance”对解释持有洞察力。
$ rlwrap ocaml
OCaml version 4.00.1
# let f o = o#x + o#y ;;
val f : < x : int; y : int; .. > -> int = <fun>
#
上面的函数f
接受任何包含方法o
和x : int
的对象y : int
。请注意,不是从某些类c
继承的对象,其中可以提前修复这些方法的偏移量。 使用这些方法的任何对象。我想这很难实现,可能是雅克在他的信息中提到的案例之一。
答案 1 :(得分:4)
有人可以解释为什么会这样吗?
使用标称键入时,可以在编译时为每个方法分配一个唯一的整数,因此可以通过索引到数组中找到虚函数。使用结构类型(如在OCaml中),这是不可能的,因此结构的散列(即方法名称)用于在字典中搜索虚方法的函数指针。
为什么确切的子类型(在这种情况下我假设继承)会影响这个?
子类型是虚拟调度的先决条件。
这是OCaml实施的情况还是其他语言也受此影响?
只是OCaml的实施。在F#中,我使用了反射和运行时代码生成来实现相同的效果而没有这样的调用时性能。