How to speed up the input and output of C + + in ACM competition? How to make the cin speed equal to the scanf speed? What is the quickest way to input and output?

Source: Internet
Author: User
Tags fread stdin

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);

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]);

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];
}

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];
}

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 ';
}

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);
}

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);
}

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);
}

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.

To ensure accuracy, I switched to the Windows platform and tested it. The result is the following table:

Method/Platform/time (SEC) Linux GCC Windows MinGW Windows VC2008
scanf 2.010 3.704 3.425
Cin 6.380 64.003 19.208
CIN Cancel Sync 2.050 6.004 19.616
Fread 0.290 0.241 0.304
Read 0.290 0.398 does not support
Mmap 0.250 does not support does not support
Pascal Read 2.160 4.668

From the above you can see several problems running programs on Linux platforms are generally faster than Windows. VC-compiled programs under Windows typically run faster than MinGW (minimal Gcc for Windows). VC to cancel the synchronization of CIN is not sensitive , before and after the same efficiency. Conversely, MinGW is very sensitive and has a 8 times-fold difference in efficiency. Read is a Linux system function, MinGW may have used some kind of impersonation, read more slowly than fread. The speed of Pascal's program is really not flattering.

I hope this article will enlighten you and welcome to continue the discussion with me.

Byvoid Original Reprint Please specify

by Cin.tie and Sync_with_stdio to speed up the input and output, the speed of CIN can be approximated to the scanf speed, but it is more compiler-specific.

Tie

The tie is a function that binds two streams, and the null argument returns the current output stream pointer.

1 2 3 4 5 6 7 8 9 10 11 12 13-14
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.