2009-03-15 3 views
5

La situazione è: c'è un file con 14 294 508 numeri interi senza segno e 13 994 397 numeri in virgola mobile (è necessario leggere double s). La dimensione totale del file è ~ 250 MB.Come eseguire l'input formattato velocemente da uno streaming in C++?

L'utilizzo di std::istream richiede circa 30 secondi. La lettura dei dati dal file alla memoria (basta copiare i byte, senza input formattati) è molto più veloce. C'è un modo per migliorare la velocità di lettura senza modificare il formato del file?

+0

Penso che dovresti pubblicare il tuo codice di loop – Ben

+0

Se questa è una lib di MSVC, potresti voler indagare su quanto penalità stai subendo da SECURE_SCL (attivata per impostazione predefinita). Abbi cura di capire le implicazioni di spegnerlo, però. – Functastic

+0

Siamo spiacenti, questo dovrebbe essere: _SECURE_SCL – Functastic

risposta

3

È necessario utilizzare i/o stile STL? È necessario verificare this eccellente lavoro da uno degli esperti. È uno specialista iostream di Dietmar Kuhl.

Odio suggerirlo ma dare un'occhiata alle routine di I/O formattate. Inoltre, stai leggendo nell'intero file in una volta sola?

+0

La sintassi e l'approccio non contano :) E sì, sto leggendo l'intero file. –

+0

Hai provato fscanf e gli amici? Direi di dare una possibilità e misurare. – dirkgently

1

Si potrebbe anche voler guardare biblioteca FastFormat di Matthew Wilson:

Non ho usato, ma lui fa alcune affermazioni piuttosto impressionante e ho trovato un sacco della sua altra opera merita di essere studiata e utilizzata (e rubata a volte).

+0

Supporta l'input formattato? –

+0

Crap - hai ragione ... Ha solo la formattazione dell'output. –

+0

Forse le tecniche possono essere applicate all'input – dcw

1

Non è stato specificato il formato. È possibile che tu possa memorizzarlo in una mappa, o leggere in blocchi molto grandi e elaborare in un algoritmo batch.

Inoltre, non è stato detto se si è sicuri che il file e il processo che lo leggeranno saranno sulla stessa piattaforma. Se un processo big-endian lo scrive e un processo little-endian lo legge, o viceversa, non funziona.

1

L'analisi di input da parte dell'utente (atoi & atof), di solito aumenta la velocità almeno due volte, rispetto ai metodi di lettura "universali".

0

qualcosa di veloce e sporco è quello di solo scaricare il file in una stringa standard C++, e quindi utilizzare uno stringstream su di esso:

#include <sstream> 
// Load file into string file_string 
std::stringstream s(file_string); 
int x; float y; 
s >> x >> y; 

Questo non può dare molto di un miglioramento delle prestazioni (si otterrà un maggiore accelerazione evitando iostream), ma è molto facile da provare, e potrebbe essere più veloce.