Disclaimer: This article turns from a few 1234 blogs
In the contest, when the large data is encountered, the reading file becomes the bottleneck of the running speed of the program, and it needs a faster reading mode. It is believed that almost all C + + learners have stumbled over the slow speed of the CIN machine, and have vowed not to read the data on the CIN. Others say that the speed of Pascal's read statement is not as scanf as C + +, C + + players can only anxious. is C + + really low Pascal? The answer is self-evident. An advanced method is to read the data in a flash, and then convert the string, this method is very good legend, but the specific how to never try, so today I can think of all the way to read the data to test the side, the result is amazing.
The best thing to read in a contest is to read a whole bunch of integers, so I wrote a program that generated 10 million random numbers into the data.txt, 55MB altogether. Then I wrote a program skeleton to calculate the run time, the code is as follows:
#include <ctime>
int main ()
{
int start = Clock ();
Do something
printf ("%.3lf\n", Double (Clock ()-start)/clocks_per_sec);
1 2 3 4 5 6 7 8 1 2 3 4 5 6-7 8
The easiest way to write a loop is to scanf the code as follows:
const int MAXN = 10000000;
int NUMBERS[MAXN];
void Scanf_read ()
{
freopen ("Data.txt", "R", stdin);
for (int i=0;i<maxn;i++)
scanf ("%d", &numbers[i]);
1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9-10
1 1
But what about efficiency. The test results for 2.01 seconds on my Computer Linux platform. Next is CIN, the code is as follows
const int MAXN = 10000000;
int NUMBERS[MAXN];
void Cin_read ()
{
freopen ("Data.txt", "R", stdin);
for (int i=0;i<maxn;i++)
std::cin >> numbers[i];
}
1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9-10
To my surprise, Cin took only 6.38 seconds, faster than I thought. Cin Slow is a reason, in fact, by default, CIN and stdin are always synchronized, that is to say, the two methods can be mixed, without worrying about file pointer clutter, and cout and stdout are the same, the mixture will not output order confusion. Because of this compatibility feature, CIN has a lot of extra overhead and how to disable this feature. Only one statement Std::ios::sync_with_stdio (false), so you can cancel the synchronization of the CIN to stdin. The procedure is as follows:
const int MAXN = 10000000;
int NUMBERS[MAXN];
void Cin_read_nosync ()
{
freopen ("Data.txt", "R", stdin);
Std::ios::sync_with_stdio (false);
for (int i=0;i<maxn;i++)
std::cin >> numbers[i];
}
1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10-11
What is the efficiency after canceling synchronization. The test run time reduced to 2.05 seconds, and scanf efficiency is almost the same. With this you can rest assured of using CIN and cout.
Next, let's test the process of reading the entire file, and first write a string that converts the array of functions, the following code
const int MAXS = 60*1024*1024;
Char Buf[maxs];
void Analyse (char *buf,int len = maxs)
{
int i;
numbers[i=0]=0;
for (char *p=buf;*p && p-buf<len;p++)
if (*p = = ")
numbers[++i]=0;
else
numbers[i] = numbers[i] * + *p-' 0 ';
}
1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 The 12 13
The most common way to read an entire file into a string is to use the Fread code as follows:
const int MAXN = 10000000;
const int MAXS = 60*1024*1024;
int NUMBERS[MAXN];
Char Buf[maxs];
void Fread_analyse ()
{
freopen ("Data.txt", "RB", stdin);
int len = fread (Buf,1,maxs,stdin);
Buf[len] = ' the ';
Analyse (Buf,len);
}
1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 The 12 13
The above code is incredibly efficient, with tests that read the 10 million numbers in 0.29 seconds and increase efficiency by almost 10 times times. The mastery of a method is unbeatable, but I remember fread was a encapsulated read, and if you use read directly, is it quicker? The code is as follows:
const int MAXN = 10000000;
const int MAXS = 60*1024*1024;
int NUMBERS[MAXN];
Char Buf[maxs];
void Read_analyse ()
{
int fd = open ("Data.txt", o_rdonly);
int len = read (FD,BUF,MAXS);
Buf[len] = ' the ';
Analyse (Buf,len);
}
1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 The 12 13
The test found that the run time was still 0.29 seconds, and that read did not have a special advantage. Is that the end of it? No, I can call Linux's underlying function mmap, the function of which is to map files to memory, is all read file methods to encapsulate the basic method, the direct use of mmap will do. The code is as follows:
const int MAXN = 10000000;
const int MAXS = 60*1024*1024;
int NUMBERS[MAXN];
Char Buf[maxs];
void Mmap_analyse ()
{
int fd = open ("Data.txt", o_rdonly);
int len = Lseek (fd,0,seek_end);
Char *mbuf = (char *) mmap (null,len,prot_read,map_private,fd,0);
Analyse (Mbuf,len);
}
1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11-12
After testing, the running time was shortened to 0.25 seconds, and the efficiency continued to increase by 14%. So far I have no better way to continue to improve the speed of reading files. Go back and measure Pascal's speed. The result was surprising, and it ran for 2.16 seconds. The procedure is as follows:
Const
MAXN = 10000000;
var
numbers:array[0..maxn] of Longint;
I:longint;
Begin
Assign (input, ' data.txt ');
Reset (input);
For i:=0 to MAXN do
read (numbers[i);
End.
1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10-11
To ensure accuracy, I switched to the Windows platform and tested it. The result is the following table:
Method/Platform/time (SEC)