2011-10-10 30 views
5

C'è una differenza notevole (in teoria) quando si legge un riga dopo l'altra rispetto alla lettura dell'intero file in una volta sola?Prestazioni durante la lettura di un file riga per riga rispetto alla lettura dell'intero file

Leggere l'intero file ha un impatto negativo sulla quantità di memoria utilizzata ma funziona più velocemente?

Ho bisogno di leggere un file ed elaborare ogni riga. Non so se dovrei leggere una riga alla volta e processarla, o leggere l'intero file, elaborare tutto, quindi scrivere in output.

Ho già impostato il prgm per leggere riga per riga e voglio sapere se vale la pena di cambiarlo per leggere l'intero file (non è semplice dato il mio setup).

Grazie,

+1

In teoria, l'unità dovrebbe potenzialmente cercare e leggere più spesso in un programma riga per riga, a seconda di cosa sta succedendo. In pratica, questo potrebbe non essere un problema poiché l'I/O del file buffer è probabilmente usato per leggere in blocchi più grandi. Il tuo chilometraggio varierà a seconda dei dettagli del tuo hardware e del tuo algoritmo. Quando si esegue l'ottimizzazione, è necessario prevedere di scrivere più iterazioni del programma e aggiungere il codice del timer o utilizzare un profiler per scoprire cosa richiede più tempo. – holtavolt

risposta

0

ad essere onesti, dopo aver studiato l'efficienza per un po 'durante la mia laurea, sono venuto a concludere questo sulla tua domanda: dipende da come spesso questo file sta per essere letto. Se lo leggi una sola volta, allora fai tutto, perché questo semplicemente libererebbe il processo per altri compiti. Ancora una cosa da tenere a mente, il file verrà modificato in seguito e richiederà l'aggiornamento (come in read solo la parte aggiornata?), In tal caso potrebbe essere necessario impostare un marker per ricodificare da dove leggere (e quindi di nuovo quante volte viene aggiornato?). Ma sì, se si tratta di un lavoro una tantum, andare avanti e leggerlo nel suo complesso, a patto che non sia necessario creare token di determinati valori letterali nel file. spero che questo aiuti.

+0

In qualsiasi sistema operativo moderno * nix o windows questo tipo di elementi (buffering, condivisione tra processi, marcatura degli aggiornamenti) è tutto fatto per voi dal sistema operativo. –

+0

Sono d'accordo .... a volte quando le persone prendono un'efficienza troppo seria, in realtà peggiorano le cose! cioè implementando/interferendo sul buffering, condividendo tra processi, marcando gli aggiornamenti. –

0

Leggere l'intero file in memoria non è generalmente una buona idea perché i file possono essere enormi e occupare molta memoria e, nel peggiore dei casi, esaurire la memoria. Quindi, per bilanciare le prestazioni e l'utilizzo della memoria, si legge un blocco di file in un buffer e si analizza il buffer. Quando hai finito di elaborare il blocco, leggi il blocco successivo fino a EOF.

Decidere su una buona dimensione del blocco dovrà essere fatto in base a ciò che si desidera raggiungere.

+1

Il file system farà tutto questo "blocco" per te! La sua gestione del buffer chiamata, implementando il proprio buffering sopra il buffering del sistema operativo, rallenterà solo l'utente. –

+0

@James Anderson - Hai ragione :) L'ho appena reso esclusivo in quanto l'OP ha menzionato "in teoria". – srikanta

2

Leggere l'intero file sarà leggermente più veloce, ma non molto!

Ma fai attenzione a leggere l'intero file non è scalabile in quanto sei limitato dalla memoria disponibile nel sistema, una volta che le dimensioni del file superano le dimensioni della RAM avaibale al tuo programma inizieranno a utilizzare lo spazio di swap sarà molto più lento. Se la dimensione del file supera la dimensione della memoria virtuale disponibile, il programma si bloccherà.

0

Un fattore è la quantità di dati che si sta leggendo, e quindi quanto tempo impiega inizialmente il programma per eseguire, vale a dire se c'è qualche vantaggio nel lavorare sulle prestazioni.

Vedere le quotazioni in this answer per alcuni buoni consigli generali sul modo di pensare alle prestazioni del software.

(So che sei una risposta in teoria, ma questo aspetto di quando preoccupare di prestazioni è anche importante, ogni volta che si dispone di una quantità finita di tempo da spendere.)

1

Come altri, Credo che fare letture più grandi migliorerà le prestazioni della vostra applicazione, ma non aspettatevi miracoli, l'I/O è già memorizzato nel buffer del sistema operativo, quindi otterrete solo riducendo il sovraccarico di avere troppe chiamate di lettura. Leggere l'intero file in un colpo solo è pericoloso, a meno che non si conosca la dimensione massima possibile per i file di input. Un approccio più ragionevole è leggere il file in grandi blocchi.

Se si desidera migliorare ulteriormente, è necessario considerare la sovrapposizione dell'I/O con l'elaborazione. Diciamo che leggi il file di input in blocchi di 128 MB. Sul thread principale si legge il primo blocco da 128 MB e poi lo si passa a un thread di lavoro per l'elaborazione. Mentre il thread worker inizia a funzionare, il thread principale legge il secondo blocco da 128 MB. Da quel momento in poi, mentre il thread di lavoro sta elaborando il blocco N, il thread principale sta leggendo il blocco N + 1 dal disco.

0

Penso che dipenderebbe dalle esigenze della vostra applicazione (come la maggior parte delle cose, lo so). La lettura di un file da 1 MB nel nodo js è ~ 3-4 volte più veloce con fs.readFile() rispetto all'utilizzo di un flusso leggibile o di un lettore di righe per quanto riguarda solo la lettura dei file. Gli stream possono offrire prestazioni aggiuntive se il file è molto grande e si sta elaborando l'input al volo. Può anche essere l'ideale se l'applicazione sta già consumando molta memoria dato che un processo Node ha un limite di memoria di ~ 1,5 GB su sistemi a 64 bit. Anche l'elaborazione dei blocchi in ingresso può essere più efficiente se la fonte dei dati è lenta rispetto alla velocità con cui la CPU può elaborarla (archivi su HDD o nastro, connessioni di rete come TCP). Per quanto riguarda la lettura di un file in memoria e lo streaming in memoria, suppongo che la funzione chiamata overhead di emissione di eventi di dati e passaggio alla funzione di elaborazione callback rallenti il ​​processo.

Problemi correlati