On the efficiency of Cin,cout and scanf,printf

Source: Internet
Author: User
Tags fread stdin

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)

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.