2009-11-11 19 views
7

Alcune funzioni sono davvero facili da implementare in OCaml (ad esempio, carta da un elenco), ma è possibile utilizzare la mappa della biblioteca OCaml: List.mapmoduli e le prestazioni OCaml

Tuttavia, possiamo chiederci quale codice sarà più efficiente. Chiamare un modulo di una unità di compilazione separata (una libreria) può invalidare alcune ottimizzazioni possibili. Ho letto nel gruppo di notizie fa.caml che quando si chiamano le funzioni dalle librerie, vengono utilizzate le chiusure.

Ho un codice OCaml in produzione che utilizza moduli e funzioni per la programmazione generica. Per ragioni storiche il mio codice è monolitico: tutto in un unico file. Ora ho più tempo, sono disposto a separare il codice in file per tali moduli. Tuttavia, temo di poter perdere le prestazioni, perché mi ci è voluto un po 'per farlo bene. Per esempio, ho dei moduli per avvolgere oggetti complessi con numeri, quindi impongo una rappresentazione unica e un confronto veloce. Io uso quegli oggetti avvolti con Mappe, Set e mappe generiche su di essi.

Le domande sono:

  • faccio a perdere prestazioni se mi trasferisco in file separati?
  • OCaml sta facendo molte ottimizzazioni sul mio codice pieno di moduli, funtori, ecc.?

In C++, se si definisce il metodo di classe in un file .h, il compilatore può finire con l'inlining di metodi brevi, ecc. È possibile ottenerlo in OCaml utilizzando file separati?

+0

Non conosco molto l'interno del compilatore ocaml e del linker, quindi non posso rispondere alla tua domanda. Tuttavia, sarei ESTREMAMENTE sorpreso se avessi perso qualsiasi prestazione rompendo il tuo codice in moduli. Anche se hai perso alcuni millisecondi, la maggiore chiarezza del tuo codice sarebbe valsa la pena. –

+0

In C/C++ potrebbe causare un'enorme differenza. Ho milioni di oggetti, ho consultato/confrontato zillioni di volte. Una serie di riferimenti adizionali per accesso può essere molto pessima. – hectorpal

+0

Sì, ma il compilatore deve incorporare tali riferimenti in modo che in realtà non si stiano effettuando più ricerche del necessario. Che ne dici di provare a realizzare un progetto di prova con una serie di moduli fittizi e cercare di misurare se c'è qualche differenza tra la loro rottura e il loro mantenimento nello stesso file. Potrebbe essere molto meno lavoro di refactoring il tuo codice di base di lavoro. Speriamo che questo ti dia una maggiore sicurezza sul fatto che ocamlopt sarà in grado di ottimizzare il tuo codice in modo intelligente. –

risposta

9

Si può perdere qualche prestazione. Tuttavia, ci sono due fattori attenuanti:

  • Il codice compilatore nativo OCaml può fare cross-modulo inline, quindi è possibile che il codice sia inline anche attraverso le unità di compilazione separata (con un paio di avvertimenti - funzioni ricorsive e gli argomenti della funzione non sono allineati tra i moduli [1]).
  • Il codice sarà ancora abbastanza veloce e i guadagni in leggibilità e manutenibilità supereranno di gran lunga qualsiasi costo di prestazione (marginale).

Non so se OCaml defuncina il codice in cui i funtori sono definiti nello stesso file sorgente. In caso contrario, i moduli non dovrebbero aggiungere alcun risultato in termini di prestazioni superiore a quello già sostenuto dai funtori.

In generale, è mia opinione che sia meglio scrivere codice diretto, leggibile e gestibile e non preoccuparsi troppo delle caratteristiche di prestazioni microscopiche come questo a meno che il codice non si dimostri troppo lento nella pratica.

+0

Grazie Michele. Buone informazioniNaturalmente so che acquisirò la leggibilità. Quello che ho ora non è soddisfacente. Tuttavia, nel mio caso le prestazioni di runtime sono un problema critico. Ho già investito molto tempo nel passaggio da elenco a array (sto utilizzando ora la libreria Res per gli array in crescita). Ho anche tonnellate di cache e ho scelto accuratamente la struttura dei dati. Penso di essere andato giù da 10 minuti o peggiore a 10 secondi facendo quello che ho fatto. La mia preoccupazione ora riguarda principalmente i moduli che contengono la rappresentazione di milioni di oggetti. Mi dividerò comunque, ma ho bisogno di asserire l'impatto e non posso dividere tutto. – hectorpal

+0

una volta terminato il codice di refactoring, dovrebbe essere relativamente semplice spostare selettivamente alcuni moduli nel file principale, se necessario. –