Mi sto occupando di un'applicazione che ha bisogno di leggere casualmente un'intera riga di testo da una serie di file di testo potenzialmente grandi (~ 3 + GB).Come posso indicizzare in modo efficiente un file?
Le linee possono essere di lunghezza diversa.
Per ridurre GC
e creare stringhe inutili, sto usando la soluzione forniti a: Is there a better way to determine the number of lines in a large txt file(1-2 GB)? per rilevare ogni nuova riga e memorizza nel una mappa in una passata producendo così un indice di lineNo => position
cioè:
// maps each line to it's corresponding fileStream.position in the file
List<int> _lineNumberToFileStreamPositionMapping = new List<int>();
- passare attraverso l'intero file
- quando rileva un incremento
new line
lineCount
e aggiungere ilfileStream.Position
al_lineNumberToFileStreamPositionMapping
Abbiamo quindi utilizzare un'API simile a:
public void ReadLine(int lineNumber)
{
var getStreamPosition = _lineNumberToFileStreamPositionMapping[lineNumber];
//... set the stream position, read the byte array, convert to string etc.
}
Questa soluzione sta attualmente fornendo una buona prestazione ma ci sono due cose che non mi piacciono:
- Dal momento che non conosco la numero totale di righe nel file, non posso preallocare un
array
quindi devo usare unList<int>
che ha la potenziale inefficienza del ridimensionamento a raddoppiare di quello che effettivamente ho bisogno; - Utilizzo memoria, ad esempio per un file di testo di ~ 1 GB con ~ 5 milioni di righe di testo l'indice occupa ~ 150 MB Vorrei davvero diminuire il più possibile.
Tutte le idee sono molto apprezzate.
Perché l'indice 150 gb? 5 milioni di ints sono meno di 20 MB di storage grezzo, quindi dove ottieni questo valore? – DavidG
Questo è ciò che mi mostra il profiler, ma di nuovo non ho scavato più a fondo. A parte questo, 20mb sarebbe lo scenario ideale, ma in realtà potrebbe essere il doppio rispetto alla logica di ridimensionamento della 'Lista' – MaYaN
Forse dovresti usare un semplice vecchio array allora. Non sono sicuro che un 'Elenco' fornisca effettivamente qualcosa di utile qui. Una volta costruito l'elenco, convertirlo in array e lanciare la lista. – DavidG