[ASD] Spox, Spoj, szybkie wczytywanie int'ów w C

W tym semestrze zadania z spox'a wymagają jeszcze szybszego wczytywanie danych, niż rok temu, więc wielu osobą może przydać się informacja jak szybko wczytać inty z wejścia.

Jak wczytać z wejścia int'y najszybciej? Wczytując po znaku z wejścia cyfry i zamieniając na int'y kiedy 'inny znak niż cyfra'.

Do wczytywania najlepiej użyć getchar_unlocked [do użycia tylko w aplikacjach jednowątkowych - czyli takich jak na spox, zwykłe getchar robi to samo tylko, że przy każdym wczytaniu znaku chce synchronizować wątki [jeden wątek?] i wykonuje się 4 razy dłużej!], funkcja ta istnieje na 'spox.spoj.pl', jeśli na kompie jej nie macie to do testów możecie podmienić tą linijkę:

#define gc getchar_unlocked

na:

#define gc getchar

A to cała funkcja (TYLKO DLA DODATNICH!):

#define gc getchar_unlocked
void scan_integer( int* o )
{
    register int c = gc();
    int x = 0;
    for( ; ((c<48 || c>57)); c = gc() );

    for( ;c>47 && c<58; c = gc() ) {
        x = (x << 1) + (x << 3) + c - 48;
    }
    *o = x;
}

Wersja dla wszystkich int (ujemnych i dodatnich):

#define gc getchar_unlocked
void scan_integer( int* o )
{
    register int c = gc();
    x = 0;
    int neg = 0;
    for( ; ((c<48 || c>57) && c != '-'); c = gc() );
    if( c=='-' ) {
        neg=1;
        c=gc();
    }
    for( ;c>47 && c<58; c = gc() ) {
        x = (x << 1) + (x << 3) + c - 48;
    }
    if( neg )
        x=-x;
    *o = x;
}

Przykład wczytania i wyświetlenia wszystkich int'ów z wejścia dla czystego C z podstawową biblioteką 'stdio.h':

int main()
{
	int liczba;
	while(!feof(stdin))
	{
		scan_integer(&liczba);
		printf("%d ", liczba);
	}
	return 0;
}

Czas wykonania algorytmu na spox z wczytywaniem metoda:

  • cin >> x; = 0,7 sec
  • fscanf(stdin, "%d", &x); = 0,27 sec
  • scan_integer(&x); // z getchar = 0,11 sec!
  • scan_integer(&x); // z getchar_unlocked = 0,03 sec!

Więcej informacje na temat: http://stackoverflow.com/a/25388170/4047081