hai chiamato lo pfrequencies
, che, insieme con il vostro parallel-processing
tag sulla questione, suggerisce si pensa che qualcosa sta usando più thread qui. Questo non è il caso, e non è nemmeno l'obiettivo "principale" della libreria dei riduttori.
La cosa principale che i riduttori comprano è che non è necessario allocare molte celle di controllo intermedie per le sequenze pigre. Prima dell'introduzione dei riduttori, frequencies
allocava 10000000 celle cons per creare una vista sequenziale del vettore da utilizzare per reduce
. Ora che esistono i riduttori, i vettori sanno come ridurli senza creare oggetti temporanei. Ma questa funzionalità è stata trasferita in clojure.core/reduce
, che si comporta esattamente come r/reduce
(ignorando alcune caratteristiche minori che sono irrilevanti qui). Quindi stai solo confrontando la tua funzione con un identico clone di se stesso.
La libreria di riduttori include anche la nozione di fold
, che può eseguire alcuni lavori in parallelo e quindi unire insieme i risultati intermedi. Per utilizzare questo, è necessario fornire più informazioni rispetto alle esigenze di reduce
: è necessario definire come avviare un "blocco" dal nulla; la tua funzione deve essere associativa; e devi specificare come combinare i blocchi. A. Webb's answer dimostra come usare fold
correttamente, per lavorare su più thread.
Tuttavia, è improbabile che si possa trarre alcun vantaggio dal piegamento: oltre al motivo per cui nota (si rinuncia ai transienti, rispetto a clojure.core/frequencies
), la creazione di una mappa non è facilmente parallelizzabile. Se la maggior parte del lavoro in frequencies
è stato aggiunto (come sarebbe in qualcosa come (frequencies (repeat 1e6 1))
), quindi fold
sarebbe di aiuto; ma la maggior parte del lavoro è nella gestione delle chiavi nella hashmap, che alla fine deve essere single-threaded alla fine. Puoi costruire mappe in parallelo, ma poi devi unirle insieme; dal momento che questa combinazione ha un tempo proporzionale alla dimensione del chunk, piuttosto che al tempo costante, guadagni poco facendo comunque i pezzi su un thread separato.
Si dovrebbe usare 'fold' not' reduce' poichè è quasi lo stesso di core riduci – Ankur
E anche una versione 'fold' su 2 core sarà probabilmente molto più lenta della versione' clojure.core/frequenze 'che usa i transienti. –
@ankur Quando provo r/fold (e omettendo l'argomento {} seed), ottengo questo errore: ArityException Numero errato di argomenti (0) passato a: utente $ pfrequencies $ fn clojure.lang.AFn.throwArity (AFn. java: 437) –