2011-12-12 16 views
5

Mi chiedo perché abbiamo bisogno di una funzione come "% identity", che è la stessa di let a = a. Migliorerà le prestazioni usandolo?identita 'ocaml% funzione

Sto introducendo la digitazione fantasma nel mio programma, chiamando le funzioni di identità una tonnellata di volte per convertire i tipi, curioso se "% identity" può ridurre un po 'di overhead.

risposta

10

La funzione %identity fa parte dell'implementazione, non fa parte del linguaggio OCaml. Indica al compilatore (in sostanza) che non c'è niente da fare per cambiare il parametro della funzione sul suo valore di ritorno. In altre parole, dice al compilatore di continuare ad usare lo stesso valore ma di cambiare idea del tipo. Se usato in modo errato, in pratica annulla tutte le eccellenti garanzie di sicurezza del sistema di tipo OCaml. Inoltre, ovviamente, non è garantito il funzionamento in altre implementazioni della lingua (comprese le versioni future del compilatore INRIA).

La funzionalità di inlining del compilatore OCaml dovrebbe già garantire che non venga generato alcun codice per le funzioni di identità. Quindi ti consiglio di continuare a usarli.

Aggiornamento

Per rispondere a una domanda non correlata nei commenti .... Si supponga di avere la composizione e la funzione identità:

let (<<) f g x = f (g x) 
let id x = x 

poi qui ci sono le funzioni per aggiungere gli elementi di un lista, per moltiplicare gli elementi di una lista e per comporre tutte le funzioni in una lista:

# let sum l = List.fold_right (+) l 0;; 
val sum : int list -> int = <fun> 
# let product l = List.fold_right (*) l 1;; 
val product : int list -> int = <fun> 
# let composition l = List.fold_right (<<) l id;; 
val composition : ('a -> 'a) list -> 'a -> 'a = <fun> 

Esempio s:

# sum [2; 3; 5; 7];; 
- : int = 17 
# product [2; 4; 17];; 
- : int = 136 
# let mx = composition [(+) 1; (*) 10];; 
val mx : int -> int = <fun> 
# mx 2;; 
- : int = 21 

Il punto è che 0 è l'identità per addizione, 1 per la moltiplicazione, e id per composizione di funzioni. id è sempre utile, proprio come lo sono 0 e 1.

+0

Quando usiamo normalmente la funzione 'identity' (non necessariamente'% identity')? –

+0

Questo è un po 'come chiedere quando usiamo i numeri 0 e 1. In una lingua in cui le funzioni sono valori di prima classe, la funzione di identità è molto utile. –

+0

scusate, immagino che la mia domanda dovrebbe essere come potreste per favore darmi un caso utile in cui 'let f x = x' dovrebbe essere o deve essere usato? –

1

L'utilizzo di %identity come una primitiva estranea può ridurre l'overhead associato alla valutazione della chiusura dello (fun x -> x) ogni volta che viene applicato.

L'OCaml compilatori particolare caso i % primitive: bytecomp/translcore.ml associa ciascuna con una speciale incorporato nodo AST (nel caso di %identity esso viene mappato al Pidentity); i compilatori corrispondono al nodo e semplificano l'espressione a cui è applicato. Nel caso del compilatore nativo, le linee pertinenti sono:

  • asmcomp/closure.ml linee 197 e ss .: semplificare %identity applicato ad un argomento costante l'argomento stesso:

    begin match p with 
        Pidentity -> make_const_int x 
    | Pnegint -> make_const_int (-x) 
    
  • asmcomp/cmmgen.ml linea 1047 e ss .: semplificare %identity come LHS di una domanda per valutare l'argomento direttamente:

    match p with 
        (* Generic operations *) 
        Pidentity -> 
         transl arg 
    

Il compilatore di codice byte ha regole di semplificazione simili per la primitiva.