Domanda

Sto scrivendo un programma in cui le prestazioni è molto importante, ma non critico. Attualmente sto leggendo nel testo da una riga per riga FILE* e io uso fgets per ottenere ciascuna linea. Dopo aver utilizzato alcuni strumenti di performance, ho trovato che il 20% al 30% del tempo la mia applicazione è in esecuzione, è all'interno fgets.

Ci sono modi più veloci per ottenere una riga di testo? La mia domanda è single-threaded con nessuna intenzione di utilizzare più thread. Ingresso potrebbe essere da stdin o da un file. Grazie in anticipo.

È stato utile?

Soluzione

Non si dice che la piattaforma ci si trova, ma se è UNIX-like, quindi si consiglia di provare la chiamata di sistema read (), che non svolge l'ulteriore livello di buffer che fgets () et al fare. Questo può accelerare le cose un po ', d'altra parte, può anche rallentare le cose -. L'unico modo per scoprirlo è quello di provare e vedere

Altri suggerimenti

  1. Usa fgets_unlocked (), ma leggere attentamente ciò che fa prima

  2. I dati con fgetc () o fgetc_unlocked () al posto di fgets (). Con fgets (), i dati sono copiati nella memoria due volte, prima dalla libreria di runtime C da un file a un buffer interno (flusso I / O è tamponato), poi da quel buffer interno di una matrice nel programma

Leggi l'intero file in una sola volta in un buffer.

Processo linee di buffer.

Questa è la soluzione più veloce possibile.

Si potrebbe provare a ridurre al minimo la quantità di tempo che passate la lettura dal disco con la lettura di grandi quantità di dati in RAM quindi lavorando su questo. La lettura dal disco è lento, in modo da ridurre al minimo la quantità di tempo spendete fare che leggendo (idealmente) l'intero file una volta, quindi lavorare su di esso.

sorta come la cache della CPU modo riduce al minimo il tempo di CPU in realtà risale al RAM, è possibile utilizzare RAM per ridurre al minimo il numero di volte che effettivamente andare su disco.

A seconda dell'ambiente, utilizzando setvbuf () per aumentare la dimensione del buffer interno utilizzato dai flussi di file può o non può migliorare le prestazioni.

Questa è la sintassi -

setvbuf (InputFile, NULL, _IOFBF, BUFFER_SIZE);

Dove InputFile è un file * in un file appena aperto utilizzando fopen () e BUFFER_SIZE è la dimensione del buffer (che viene allocato dal presente invito a voi).

È possibile provare varie dimensioni del buffer per vedere se qualcuno ha un'influenza positiva. Si noti che questo è del tutto facoltativo, e il vostro tempo di esecuzione può fare assolutamente nulla con questa chiamata.

Se i dati provengono dal disco, si potrebbe essere legato IO.

Se questo è il caso, ottenere un disco più veloce (ma primo controllo che state ottenendo il massimo da quello esistente ... alcune distribuzioni di Linux non ottimizzano l'accesso al disco fuori dalla scatola (hdparm)), in scena i dati in memoria (ad esempio copiandolo in un disco RAM) prima del tempo, o essere disposti ad aspettare.


Se non si IO vincolati, si potrebbe essere sprecare un sacco di tempo di copia. Si potrebbe beneficiare di cosiddetti metodi di zero-copy. Qualcosa di simile a memoria la mappa il file e accedere solo tramite puntatori.

Questo è un po 'oltre la mia esperienza, così si dovrebbe fare qualche lettura o attendere per un aiuto più informato.

BTW-- Si potrebbe essere sempre in più lavoro che il problema è la pena; forse una macchina più veloce avrebbe risolto tutti i tuoi problemi ...

NB-- Non è chiaro che si può memoria mappare l'input standard o ...

Se vuoi in fread (). Si legge molto più veloce per me, soprattutto se buffer per fread è impostato su 65536. Contro: quello che dovete fare un sacco di lavoro ed essenzialmente scrivere la propria funzione getline convertire da lettura binario in testo. Partenza: file di I / O

Se il sistema operativo lo supporta, si può provare a leggere il file asincrona, vale a dire, il file viene letto nella memoria mentre la CPU è occupato a fare qualcos'altro. Quindi, il codice più o meno così:

start asynchronous read
loop:
  wait for asynchronous read to complete
  if end of file goto exit
  start asynchronous read
  do stuff with data read from file
  goto loop
exit:

Se avete più di una CPU, allora una CPU legge il file e analizza i dati in linee, l'altra CPU prende ogni linea e lo elabora.

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