Per trovare il modo più veloce per leggere un file riga per riga dovrai fare alcuni benchmark. Ho eseguito alcuni piccoli test sul mio computer ma non puoi aspettarti che i miei risultati si applichino al tuo ambiente.
Utilizzando StreamReader.ReadLine
Questo è fondamentalmente il tuo metodo. Per qualche motivo si imposta la dimensione del buffer sul valore più piccolo possibile (128). Aumentare questo in generale aumenterà le prestazioni. La dimensione predefinita è 1.024 e altre buone scelte sono 512 (la dimensione del settore in Windows) o 4.096 (la dimensione del cluster in NTFS). Dovrai eseguire un benchmark per determinare una dimensione ottimale del buffer. Un buffer più grande è - se non più veloce - almeno non più lento di un buffer più piccolo.
const Int32 BufferSize = 128;
using (var fileStream = File.OpenRead(fileName))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) {
String line;
while ((line = streamReader.ReadLine()) != null)
// Process line
}
Il FileStream
costruttore consente di specificare FileOptions . Ad esempio, se stai leggendo un file di grandi dimensioni in sequenza dall'inizio alla fine, potresti trarne vantaggio FileOptions.SequentialScan
. Ancora una volta, il benchmarking è la cosa migliore che puoi fare.
Utilizzando File.ReadLines
Questo è molto simile alla propria soluzione, tranne per il fatto che è implementato usando un StreamReader
con una dimensione del buffer fissa di 1.024. Sul mio computer ciò si traduce in prestazioni leggermente migliori rispetto al codice con una dimensione del buffer di 128. Tuttavia, è possibile ottenere lo stesso aumento delle prestazioni utilizzando una dimensione del buffer maggiore. Questo metodo è implementato usando un blocco iteratore e non consuma memoria per tutte le linee.
var lines = File.ReadLines(fileName);
foreach (var line in lines)
// Process line
Utilizzando File.ReadAllLines
Questo è molto simile al metodo precedente, tranne per il fatto che questo metodo aumenta un elenco di stringhe utilizzate per creare l'array di righe restituito, quindi i requisiti di memoria sono più elevati. Tuttavia, ritorna String[]
e non IEnumerable<String>
ti consente di accedere in modo casuale alle linee.
var lines = File.ReadAllLines(fileName);
for (var i = 0; i < lines.Length; i += 1) {
var line = lines[i];
// Process line
}
Utilizzando String.Split
Questo metodo è notevolmente più lento, almeno su file di grandi dimensioni (testato su un file da 511 KB), probabilmente a causa della sua String.Split
implementazione. Alloca anche un array per tutte le linee aumentando la memoria richiesta rispetto alla tua soluzione.
using (var streamReader = File.OpenText(fileName)) {
var lines = streamReader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
// Process line
}
Il mio consiglio è di usarlo File.ReadLines
perché è pulito ed efficiente. Se sono necessarie opzioni di condivisione speciali (ad esempio, si utilizza FileShare.ReadWrite
), è possibile utilizzare il proprio codice ma è necessario aumentare le dimensioni del buffer.
Fastest
vuoi dire dal punto di vista delle prestazioni o di sviluppo?