Desidero leggere tutte le righe di un file di 1 GB di grandi dimensioni il più velocemente possibile in un Stream<String>
. Attualmente sto usando Files(path).lines()
per quello. Dopo aver analizzato il file, sto facendo alcuni calcoli (map()
/filter()
) Inizialmente ho pensato che fosse già fatto in parallelo, ma sembra che io abbia torto: Durante la lettura del file così com'è, ci vogliono circa 50 secondi sul mio laptop con doppia CPU. Tuttavia, se divido il file usando i comandi bash e poi li elabro in parallelo, ci vogliono solo circa 30 secondi.Come leggere tutte le righe di un file in parallelo in Java 8
Ho provato le seguenti combinazioni:
- singolo file, senza linee parallele() Stream ~ 50 secondi
- fila indiana,
Files(..).lines().parallel().[...]
~ 50 secondi - due file, senza linee parallele() Strean ~ 30 secondi
- due file,
Files(..).lines().parallel().[...]
~ 30 secondi
ho eseguito questi 4 più volte con più o meno gli stessi risultati (di 1 o 2 secondi). Lo [...]
è una catena di mappe e solo filtro, con un toArray(...)
alla fine per attivare la valutazione.
La conclusione è che non vi è alcuna differenza nell'uso di lines().parallel()
. Poiché la lettura di due file in parallelo richiede meno tempo, si ottiene un aumento delle prestazioni dalla divisione del file. Tuttavia sembra che l'intero file sia letto in serie.
Modifica: Voglio sottolineare che utilizzo un SSD, quindi è praticamente alla ricerca di tempo. Il file ha 1658652 (relativamente brevi) linee in totale. dividere il file in bash impiega circa 1,5 secondi: time split -l 829326 file # 829326 = 1658652/2 split -l 829326 file 0,14s user 1,41s system 16% cpu 9,560 total
Quindi la mia domanda è: esiste alcuna classe o funzione in Java 8 JDK che può parallelizzare la lettura di tutte le linee, senza dover dividere prima? Ad esempio, se ho due core CPU, , il primo lettore di righe dovrebbe iniziare dalla prima riga e un secondo dalla riga (totalLines/2)+1
.
Che cosa intendi _split il file utilizzando bash_? Inoltre, devi leggere il file per trovare le linee. Non può solo sapere dove sono i terminatori di linea. –
@SotiriosDelimanolis È possibile passare a un punto arbitrario nel file e cercare la prima nuova riga e dividere in quel modo senza elaborare prima tutti i dati nell'intero segmento. –
In bash, puoi usare 'split -l # lines', combinalo con' wc -l' per dividerlo in due parti. Micheal Petch ha capito la mia idea :) – user3001