2012-12-09 52 views
12

閱讀CAML的名單上一些老的帖子中,我由雅克·加里奎斯遇到下列此帖一:http://caml.inria.fr/pub/ml-archives/caml-list/2007/11/24e8215c8d844b05db58ed3f79c9645f.en.html爲什麼方法調度有時很慢?

的報價,我關心的是以下幾點:

方法調用任意對象可能會很慢。這是因爲,由於 子類型,在某些情況下,無法知道方法 將在表中的位置,並且必須執行二分搜索。

有人可以解釋爲什麼這種情況?爲什麼子類型(我在這種情況下假設的繼承)會影響到這一點? OCaml的實現是這種情況嗎?或者其他語言也會遭受這種情況?

請指點我對此的進一步資源,谷歌已經失敗了我。

+3

Subtyping!=繼承。 – delnan

+0

嗯,看起來像我有一些閱讀要做... – rgrinberg

回答

4

有人可以解釋爲什麼會出現這種情況嗎?

使用標稱類型,可以在編譯時爲每個方法分配一個唯一的整數,因此可以通過索引到數組中找到一個虛擬函數。對於結構類型(如在OCaml中),不能這樣做,因此使用結構的散列(即方法名稱)來搜索字典中的虛擬方法的函數指針。

爲什麼子類型(繼承我在這種情況下假設)正在影響這?

子類型是虛擬調度的先決條件。

這是OCaml的實現情況還是其他語言遭受這種情況呢?

剛剛OCaml的實施。在F#中,我使用了反射和運行時代碼生成來實現相同的效果,而不會導致這樣的調用時間性能。

+0

這是一個很好的答案,但我仍然不清楚二進制搜索的確切位置。 – rgrinberg

+0

你有一些開源示例代碼嗎? – Demi

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接受具有方法x : inty : int任何對象o。請注意,不是從某些類別中繼承的對象,其中這些方法的偏移量可能已經提前修復,請注意。 任何對象與這些方法。我想這很難實施,並且可能是雅克在其消息中提到的一個案例。

+0

謝謝帕斯卡爾。我仍然不明白爲什麼查找應該不僅僅是在適當的vtable中查找散列表。也許我應該看看OCaml的酸性代碼。在任何情況下,如果沒有其他人有解釋,我會接受你的答案... – rgrinberg

+4

@rgrinberg你說「哈希表查找」就好像它是最便宜的可能實現,但事實並非如此。與使用編譯時常量索引的數組查找相比,散列表查找和二進制搜索(顯然實際使用的)都顯着(對於此抽象級別)較慢。 – delnan

+1

@delnan我認爲他假設哈希表查找會比二分查找更快,並想知道爲什麼不使用哈希表。 – asm