2010-06-26 11 views
19

Non sono sicuro se questo appartiene a StackOverflow o nel gruppo Clojure Google. Ma il gruppo sembra essere occupato a discutere su numeric improvements for Clojure 1.2, quindi proverò qui:Clojure numero crunch prestazioni

http://shootout.alioth.debian.org/ ha un numero di benchmark delle prestazioni per varie lingue.

Ho notato che mancava Clojure, quindi ho creato una versione Clojure di n-body problem.

Il codice più veloce sono stato in grado di produrre può essere found here, e benchmarking sembra voler dire che per macinare numeri Clojure è

  • fattore ~ ​​10 più veloce di Python/Rubino/Perl
  • fattore ~ 4 più lento di C/Java/Scala/Ada
  • circa alla pari con OCaml, Erlang e Go

sono abbastanza contento con quel livello di prestazioni.

La mia domanda per i guru Clojure è

  • Vi sono miglioramenti evidenti che ho perso, sia in termini di velocità o in termini di brevità codice o la leggibilità (senza sacrificare la velocità)?
  • Lo consideri rappresentativo delle prestazioni Clojure rispetto a Python/Ruby/Perl da una parte e Java/C dall'altra?

Aggiornamento

Più Clojure 1.1 programmi di riferimento per la sparatoria here, tra cui il problema n-corpo.

+0

Devo immaginare che la JVM abbia un ruolo importante qui. Che JVM stai usando? Stai usando lo stesso tipo della sparatoria? –

+0

Java 1.6.0, il java standard fornito con OS X 10.6. È approssimativamente la stessa JVM (io: 1.6.0_20, shootout: 1.6.0_18) ma computer diverso rispetto alla sparatoria. Ho eseguito localmente sia Clojure che l'implementazione Java dello shootout. Ho stimato le prestazioni relative utilizzando Java come base di riferimento e ridimensionando di conseguenza i risultati delle prove. –

+0

Il tuo codice sembra abbastanza buono. Con i miglioramenti primitivi in ​​1.2, mi aspetto che tu possa essere abbastanza vicino al tempo di Java. Hai provato a eseguirlo attraverso un profiler? Il mio sospetto è che qualcosa da qualche parte stia aggiungendo un overhead di boxe o funzione che ti fa male. – mikera

risposta

4

Mi chiedo se Cantor potrebbe essere utile per voi - è una libreria matematica ad alte prestazioni per Clojure. Vedi anche this thread nel gruppo Google, che tratta di un progetto simile nel contesto delle nuove primitive operazioni aritmetiche.

+0

Cantor sembra utile, darò un'occhiata. Grazie! –

11

Non una valanga di risposte qui :) ma a quanto pare un certo interesse, quindi cercherò di rispondere alla mia domanda con quello che ho imparato nel corso degli ultimi giorni:

  • Con l'approccio di ottimizzazione 1.1 (Primitive e array mutabili di Java) ~ 4 volte più lento di Java ottimizzato è veloce quanto basta.
  • 1.2 costrutti definterface e deftype sono più di due volte più veloce, rientranti ~ 1.7x (+ 70%) di Java con il codice più corto, più semplice e più pulito rispetto a 1,1.

Ecco le implementazioni:

More details comprese le immagini di "lezioni apprese", versione JVM e profiling.

Soggettivamente, l'ottimizzazione del codice 1.2 era un gioco da ragazzi rispetto all'ottimizzazione di 1.1, quindi questa è un'ottima notizia per il numero di Clojure. (In realtà vicino al fantastico :)

Il test 1.2 utilizzato il ramo master corrente, non ho provato nessuno dei nuovi rami numerici. Da quello che ho potuto capire le nuove idee attualmente in discussione

  • può rendere non ottimizzato numerici più veloce
  • può accelerare la versione 1.1 di questo benchmark
  • non sarà probabilmente accelerare la versione 1.2, è già come "vicino al metallo" in quanto è probabile che arrivi.

Avvertenze:

  • Clojure 1.2 non è ancora stato rilasciato, in modo da 1.2 risultati dei benchmark sono preliminari.
  • Questo è un punto di riferimento particolare per i calcoli fisici. È rilevante per il calcolo del numero in virgola mobile, ma irrilevante per le prestazioni in aree come l'analisi delle stringhe, la concorrenza o la gestione delle richieste web.
+1

Dovresti provare i rami numerici, guardando oltre il tuo codice. Vedo dei posti dove riceverai inutilmente la boxe sotto il ramo principale 1.2. – dnolen

+0

Grazie per il suggerimento. Il ramo equiv ha avuto un certo impatto sulla versione 1.1, nessuna differenza apprezzabile per la versione 1.2. Ci possono essere implementazioni alternative dove la differenza è più significativa. Il ramo equiv va ancora bene, soprattutto i suggerimenti di tipo primitivo e: statico. –

+0

Grazie mille per il tuo contributo molto interessante. Ho particolarmente apprezzato la lettura dell'analisi dettagliata. Ho compilato la versione 1.2 e l'ho confrontato con l'esempio Java in diverse esecuzioni ed era in media solo 1,5 volte più lento. Due domande sono state evocate da parte mia. Come hai affermato nella tua analisi, il codice non è idiomatico perché fa uso di variabili mutabili. Quanto più lento sarebbe il codice se venissero usate variabili immutabili? Quanto impegno ci sarebbe nel parallelizzare la versione mutabile o immutabile? –

4

Questa è una domanda un po 'vecchio e le risposte attuali sono un po' fuori moda, quindi mi piacerebbe aggiungere un aggiornamento a partire da metà 2013 per chi è interessato a "macinare numeri" in Clojure

C'è stato molto successo nello spazio Clojure Numerical Computing:

  • Clojure 1.5 è ora disponibile, che ha un sacco di supporto migliorato per le operazioni numeriche. Nella maggior parte dei casi, è ora possibile ottenere molto vicino alla velocità di Java puro
  • Un newsgroup dedicato - Numerical Clojure
  • core.matrix ora offre un'API idiomatica per la matematica matrice/calcolo numerico che supporta più implementazioni di back-end (compresi BLAS nativi biblioteche)

Disclaimer: Sono un manutentore/collaboratore di molti dei precedenti.