Fast I/O


#1

Anche se ormai la lettura diretta da file sta cadendo in disuso, vorrei sapere, per cultura personale, tutti i trucchetti per leggere e scrivere su file nel modo più veloce.


#2

Io conosco solo quello che fa uso della funzione getc_unlocked(in) dove “in” è lo stream di input (stile C con i puntatori FILE*). Usando questa funzione leggi dallo stream un carattere alla volta (quindi compresi spazi, invii, ecc). Quindi per poterlo usare ti dovresti creare un parser di interi.


#3

Come già diceva Lawliet, probabilmente il modo migliore è usare getc_unlocked (il che non esclude che ci siano metodi più veloci, ma meno facili da implementare). Il parser di interi sarebbe qualcosa del genere (usando per comodità getchar_unlocked(), che legge da stdin):

int fast_read_int() {
int c, n = 0;
do c = getchar_unlocked();
while(c < ‘0’ || c > ‘9’);
do {
n = (n << 3) + (n << 1) + (c - ‘0’);
c = getchar_unlocked();
} while(c >= ‘0’ && c <= ‘9’);
return n;
}

(n << 3) + (n << 1) è solo un modo un pochino più veloce di scrivere n * 10. Se necessario, la funzione può facilmente essere modificata per leggere anche interi negativi (basta controllare la presenza di un carattere ‘-’). Se ti interessa anche l’output veloce, non dovrebbe essere troppo difficile scrivere una funzione simile che utilizzi putchar_unlocked (devi fare attenzione a un paio di cose, ossia che devi scrivere il numero al contrario e tenere conto degli zeri alla fine). Ma come hai giustamente detto, ormai si tende a utilizzare la lettura/scrittura da/su file sempre meno.


Cottarelle in classe
Cottarelle in classe
#4
Ma come hai giustamente detto, ormai si tende a utilizzare la lettura/scrittura da/su file sempre meno.

Delfad0r

Per fortuna, aggiungerei :)

#5

Se può ancora interessarti ho scritto una piccola classe in c++ che legge da file moooolto velocemente… Usare open/read e un buffer. Il main è un piccolo benchmark di confronto con scanf che crea un file di un centinaio di MB e lo legge. In teoria dovrebbe funzionare, su 10.000.000 di interi positivi nessun assert fallisce, io non mi fiderei troppo ad usarla però…

A scopi didattici: https://gist.github.com/edomora97/04710b044a1205b03763

Buon divertimento!

PS:
il benchmark sul mio PC:
File sample.txt 104.827.494 byte (10000001 interi)
scanf: 1064ms
FileReader: 180ms

Not bad