Sunday, June 12, 2011

SPOJ 450. Enormous Input Test Problem Code: INTEST


This problem also appears in CodeChef ---here---

This problem is to test how fast you are able to read the input. Faster input output methods are required for some problems in UVa, SPOJ, CodeChef and other sites (Usually the problem statements have a warning that the IO is huge).

What I found out about faster IO:

Never use cin or cout. Always use scanf and printf (they are about twice faster). But there are methods much much faster than scanf and printf!!

My first solution to the above problem: was using scanf and printf. -->Execution time: 5.44 s

Then I googled to find out this function to read integers using getchar:

inline void fastRead(int *a)
{
register char c=0;
while (c<33) c=getchar();
*a=0;
while (c>33)
{
*a=*a*10+c-'0';
c=getchar();
}
}
I used it and my execution time became reduced by 2 seconds  to 3.40 s 
I then stumbled upon UVa forum where someone suggested that getchar_unlocked is faster than getchar. So I modified the function to use getchar_unlocked:

inline void fastRead(int *a)
{
register char c=0;
while (c<33) c=getchar_unlocked();
*a=0;
while (c>33)
{
*a=*a*10+c-'0';
c=getchar_unlocked();
}
}
I submitted the program again with the getchar_unlocked modification and my execution time is now believe it or not: 0.76 s

Check this out:

10 comments:

Amit said...

wow, i was looking for the faster input output method and this is awesome .

And i also heard fread function is much faster . is it ?
and please keep posted new things .

Anonymous said...

Hi,

Can you please help me understand the function fastRead?I am not getting how the two while loops are working.

Vijay S. said...

Thanks everyone for comments...

@Amit
Fread reads blocks of data at once... so I think should be faster. Should try it out :P

@Anonymous

To read an integer x, call the function like this:

fastRead(&x);

What it does:

The ascii value of '\n' is 10.
The ascii value of ' ' is 32.

The function reads all the empty lines and spaces till it encounters a digit. (while (c<33))

If the input is like this:

(newline)
(space)(space)123

The function reads all the newlines and spaces till it encounters the character '1'.

From then, it builds the integer character by character like this:

0 (initial value)
1 (shifts 0 to the left(to get 0) and adds the first character)
10 + 2 (shifts 1 to the left(to get 10) and adds the second character)
120 + 3 (shifts 12 to the left(to get 120) and adds the third character)

And it continues reading till it encounters a space or '\n' signifying the end of the number. (while(c>33))

Note:
Since every digit is a character, it is in ASCII. ie., '0' is 48, '1' is 49, and so on...
Therefore to get the number 1 from character '1', we have to subtract 48 or '0'.

Anonymous said...

great explainations.......

Anonymous said...

Very useful post. Thanks bro

abhinav said...

Can you please explain what the two while loops are used for??

Anonymous said...

Really awesome and helpful post , but can somebody give an example on how to implement it ?

Surabhi said...

really very nice

Anonymous said...

awesome

Anonymous said...

really helping