2012-12-09 11 views
12

Leggendo alcuni vecchi messaggi su caml-list mi sono imbattuto il seguente post da Jacques Garrigues: http://caml.inria.fr/pub/ml-archives/caml-list/2007/11/24e8215c8d844b05db58ed3f79c9645f.en.htmlPerché la spedizione del metodo a volte rallenta?

La citazione che mi interessa è il seguente:

Metodo invita oggetti arbitrari può essere lento. Questo perché, a causa del sottotitolo , in alcune situazioni non c'è modo di sapere dove il metodo sarà nella tabella, e una ricerca binaria deve essere fatta.

Qualcuno può spiegare perché questo è il caso? Perché esattamente il sottotipo (l'ereditarietà che sto assumendo in questo caso) sta influenzando questo? È questo il caso dell'implementazione di OCaml o anche altre lingue ne soffrono?

Prego indicarmi ulteriori risorse in merito, google mi ha fallito.

+3

Sottotipizzazione! = Ereditarietà. – delnan

+0

Hmm, sembra che abbia qualche lettura da fare ... – rgrinberg

risposta

4

Qualcuno può spiegare perché questo è il caso?

Con la digitazione nominale a ciascun metodo è possibile assegnare un numero intero univoco in fase di compilazione, in modo che sia possibile trovare una funzione virtuale indicizzandola in una matrice. Con la tipizzazione strutturale (come in OCaml) questo non può essere fatto in modo che un hash della struttura (cioè il nome del metodo) sia usato per cercare il puntatore di funzione del metodo virtuale in un dizionario.

Perché esattamente il sottotipo (l'ereditarietà che sto assumendo in questo caso) sta influenzando questo?

I sottotipi sono un prerequisito per la spedizione virtuale.

È questo il caso dell'implementazione di OCaml o anche altre lingue ne soffrono?

Solo l'implementazione di OCaml. In F #, ho usato la riflessione e la generazione del codice di runtime per ottenere lo stesso effetto senza un impatto sulle prestazioni del tempo di invocazione.

+0

Questa è una buona risposta, ma non sono ancora chiaro dove la ricerca binaria arriva esattamente. – rgrinberg

+0

Hai qualche codice di esempio open source? – Demi

10

Penso che il commento di delnan che, in OCaml, "Sottotitolo! = Ereditarietà" contiene l'intuizione della spiegazione.

$ rlwrap ocaml 
     OCaml version 4.00.1 

# let f o = o#x + o#y ;; 
val f : < x : int; y : int; .. > -> int = <fun> 
# 

Funzione f sopra accetta qualsiasi oggetto o che ha metodi x : int e y : int. Non oggetti che ereditano da qualche classe c in cui un offset per questi metodi potrebbe essere stato fissato in anticipo, attenzione. Qualsiasi oggetto con questi metodi. Immagino che sia difficile da attuare e potrebbe essere uno dei casi a cui Jacques si riferisce nel suo messaggio.

+0

Grazie Pascal. Ancora non capisco perché la ricerca dovrebbe essere qualcosa di più di una tabella hash cercare in un vtable appropriato. Forse dovrei dare un'occhiata al codice sorgente di OCaml. In ogni caso accetterò la tua risposta se nessun altro ha una spiegazione ... – rgrinberg

+4

@rgrinberg Dici "hash table lookup" come se fosse l'implementazione più economica possibile, ma non è vero.Sia la ricerca della tabella hash che la ricerca binaria (che è apparentemente effettivamente utilizzata) sono significativamente più lente (per questo livello di astrazione) rispetto a una ricerca di array con un indice costante in fase di compilazione. – delnan

+1

@delnan Penso che stia partendo dal presupposto che una ricerca nella tabella hash sarebbe più veloce di una ricerca binaria e si chiederà perché invece non si usi una tabella hash. – asm

Problemi correlati