Domanda

Sono stato informato che la mia libreria è più lenta di quanto dovrebbe essere, nell'ordine di oltre 30 volte troppo lento durante l'analisi di un determinato file (file di testo, dimensione 326 kb). L'utente ha suggerito che forse sto usando std :: ifstream (presumibilmente invece di FILE ).

Preferirei non riscrivere ciecamente, quindi ho pensato di controllare prima qui, dal momento che la mia ipotesi sarebbe che il collo di bottiglia è altrove. Sto leggendo carattere per carattere, quindi le uniche funzioni che sto usando sono get () , peek () e tellg () / seekg () .

Aggiornamento:

Ho profilato, e ho confuso output - gprof non sembrava pensare che ci fosse voluto lungo. Ho riscritto il programma per leggere prima l'intero file in un buffer e ha accelerato di circa 100x. Penso che il problema potrebbe essere stato il tellg () / seekg () che ha impiegato molto tempo, ma gprof potrebbe non essere stato in grado di vederlo per qualche motivo. In ogni caso, ifstream non sembra bufferizzare l'intero file, anche per queste dimensioni.

È stato utile?

Soluzione

Non penso che farebbe la differenza. Soprattutto se stai leggendo char con char, è probabile che il sovraccarico dell'I / O domini completamente qualunque cosa . Perché leggi singoli byte alla volta? Sai quanto sia estremamente inefficiente?

Su un file 326kb, la soluzione più rapida sarà molto probabilmente quella di leggerlo in memoria contemporaneamente.

La differenza tra std :: ifstream e gli equivalenti C, è sostanzialmente una chiamata di funzione virtuale o due. Potrebbe fare la differenza se eseguito poche decine di milioni di volte al secondo, altrimenti non reale. l'I / O dei file è generalmente così lento che l'API utilizzata per accedervi non ha importanza. Ciò che conta di più è il modello di lettura / scrittura. Molte ricerche sono cattive, letture / scritture sequenziali buone.

Altri suggerimenti

Dovrebbe essere leggermente più lento, ma come quello che hai detto, potrebbe non essere il collo di bottiglia. Perché non modifichi il tuo programma e vedi se è così?

Penso che sia improbabile che il tuo problema venga risolto passando da fstream a FILE *, di solito entrambi sono bufferati dalla libreria C. Anche il sistema operativo può memorizzare nella cache le letture (linux è molto buono in questo aspetto). Data la dimensione del file a cui stai accedendo è molto probabile che sarà interamente in RAM.

Come PolyThinker afferma che la soluzione migliore è eseguire il programma attraverso un profiler e determinare dove si trova il problema.

Inoltre stai usando seekg / tellg questo può causare notevoli ritardi se il tuo disco è fortemente frammentato, perché per leggere il file per la prima volta il disco deve spostare le testine nella posizione corretta.

Tutti i benchmark sono malvagi. Profila semplicemente il tuo codice per i dati che ti aspetti.

Ho eseguito un confronto delle prestazioni I / O tra Ruby, Python, Perl, C ++ una volta. Per i miei dati, versioni linguistiche, ecc. La variante di C ++ è stata più volte più lenta (era una grande sorpresa in quel momento).

Sono d'accordo che dovresti profilare. Ma se stai leggendo il file un personaggio alla volta, che ne dici di creare un file mappato in memoria? In questo modo puoi trattare il file come un array di caratteri e il sistema operativo dovrebbe occuparsi di tutto il buffering di basso livello per te. La soluzione più semplice e probabilmente più veloce è una vittoria nel mio libro. :)

Qui è un ottimo benchmark che mostra che in condizioni estreme, fstream sono in realtà piuttosto lenti ... a meno che:

  1. Usi il buffering (non posso sottolinearlo abbastanza)
  2. Manipoli tu stesso il buffer (vale a dire, se hai bisogno di prestazioni come OP nella domanda collegata), che non è così diverso dall'uso di FILE * .

Tuttavia, non dovresti ottimizzare prematuramente. I fstreams sono generalmente migliori e se devi ottimizzarli lungo la strada, puoi sempre farlo in un secondo momento con pochi costi. Per prepararsi al peggio in anticipo, suggerisco di creare un proxy minimo per fstream ora in modo da poterlo ottimizzare in un secondo momento, senza dover toccare nient'altro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top