Qual è il modo più efficiente per elaborare file binari di grandi dimensioni in Haskell?Il modo più efficiente per cercare in un file di grandi dimensioni
La risposta standard è leggere l'intero file come un ByteString pigro e quindi utilizzare qualcosa come il pacchetto binario per scrivere un parser su di esso. Ci sono un paio di problemi con quella ...
In primo luogo, librerie come binario non veramente gestire analizza il fallimento, e sono esplicitamente aspettandosi analisi a fallire a volte.
In secondo luogo, non sto analizzando l'intero contenuto del file. Ho intenzione di saltare molti pezzi di esso. E leggere i gigabyte di dati dal disco alla RAM solo per fare in modo che il garbage collector lo butta via di nuovo sembra piuttosto poco performante.
In relazione a ciò, devo essere in grado di dire se il salto che voglio eseguire mi porterà alla fine del file o meno (ed errore se lo fa).
Potrebbe anche essere necessario cercare indietro, o forse in uno specifico byte offset all'interno del file, che non sembra essere ben supportato da un approccio ByteString pigro. (C'è un grave pericolo di finire per contenere l'intero file nella RAM.)
L'alternativa, ovviamente, è leggere singoli byte uno alla volta, intercalati con i comandi hSeek
. Ma ora il problema è: quanto è efficiente la lettura di un file un byte alla volta? Sembra che potrebbe anche essere piuttosto lento. Non sono sicuro che sia hSetBuffering
abbia un effetto su questo. (?)
Quindi, naturalmente, c'è mmap
. Ma sembra che impazzire il sistema di memoria virtuale se usato su file di grandi dimensioni. (Che è strano, considerando che è l'intero scopo per esso esistente ...)
Cosa pensiamo, gente? Qual è il modo migliore per avvicinarsi a questo, in termini di prestazioni I/O e manutenibilità del codice?
Che dire 'hGetBuf',' 'hGetBufNonBlocking' e hGetSome'? Puoi leggere in thunk più grandi di singoli byte. –
Utilizzare [a mmap'd bytestring] (http://hackage.haskell.org/packages/archive/bytestring-mmap/0.2.2/doc/html/System-IO-Posix-MMap-Lazy.html)? L'indicizzazione quindi carica solo i blocchi richiesti dalla memoria. –
Mi aggiro su come tutto questo interagisce con 'hSetBuffering'? – MathematicalOrchid