Fast I/O

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.

1 Mi Piace

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.

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.

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

Delfad0r

Per fortuna, aggiungerei :)

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

Ciao edomora, MyK_00L mi ha fatto notare che la tua classe si bugga quando in un file non c’è uno spazio finale, in pratica il programma si inceppa. Ho provato per ore senza una soluzione al problema (purtroppo), però da quello che ho capito è la funzione skipspaces che dà problemi, in quanto non trovando più nessun carattere non restituisce né vero né falso.

7 Mi Piace

ma bro

8 Mi Piace

ma bro

9 Mi Piace

ma bro

8 Mi Piace

ma bro

6 Mi Piace

ma bro

6 Mi Piace

ma bro

6 Mi Piace

ma bro

8 Mi Piace

ma che è? un meme?

ma bro

7 Mi Piace

ma bro

7 Mi Piace

ma bro

8 Mi Piace

ma bro

3 Mi Piace

ma bro

2 Mi Piace

ma bro

2 Mi Piace