×

Search anything:

Optimized Input Output I/O in C++

Internship at OpenGenus

Get this book -> Problems on Array: For Interviews and Competitive Programming

In this article, we have presented how to optimize input and output I/O in C++. This is critical as input and output consume the majority of the execution time and is critical in time critical applications and in competitive programming contests.

Table of contents:

  1. Fastest I/O functions
  2. Use ios_base::sync_with_stdio
  3. cin and cout
  4. Avoid use of endl
  5. Conclusion

Fastest I/O functions

There are several I/O functions in C and C++ such as printf, scanf, write, fwrite, cout, cin, read, fread putchar and much more.

Following is the ordered list of I/O functions dealing with integers in ascending order (faster to slowest):

  • printf (fastest for integer)
  • scanf
  • write
  • fwrite
  • cout
  • cin (slowest for integer)

Following is the ordered list of I/O functions dealing with characters/ strings in ascending order (faster to slowest):

  • read (fastest for character)
  • fread
  • printf
  • getchar
  • putchar
  • cout
  • scanf
  • cin (slowest for character)

The straight conclusion is:

  • For integer input, use scanf and for character input, use read.
  • For both integer and character output, use printf.

This is true for most standard systems. To test the order for your own system, use the following C++ program which we used to benchmark the different I/O functions:

// Benchmark to test I/O functions in C++
// Part of iq.opengenus.org
#include <iostream>
#include <string>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <iomanip>
#include <cctype>
using namespace std;
 
const int N=10000000,NC=10*N;
int a[N],swtime,swsize;
char s[NC];
char sw[16*N];
 
void gen() {
    for (int i=0;i<N;i++) {
        a[i]=rand();
    }
    for (int i=0;i<NC;i++) {
        s[i]=rand()%10+'0';
    }
    int cur=clock();
    swsize=0;
    for (int i=0;i<N;i++) {
        char s[100];
        sprintf(s,"%d",a[i]);
        for (int j=0;s[j];j++) {
            sw[swsize++]=s[j];
        }
        sw[swsize++]=' ';
    }
    swtime=clock()-cur;
}
 
void test_printf_int() {
    int cur=clock();
    freopen("temp.txt","w",stdout);
    for (int i=0;i<N;i++)
        printf("%d ",a[i]);
    fclose(stdout);
    fprintf(stderr,"Test: (printf, %d ints) %.2lfc\n",N,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_cout_int() {
    int cur=clock();
    freopen("temp.txt","w",stdout);
    for (int i=0;i<N;i++)
        cout << a[i] << ' ';
    fclose(stdout);
    fprintf(stderr,"Test: (cout, %d ints) %.2lfc\n",N,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_write_int() {
    int cur=clock();
    freopen("temp.txt","w",stdout);
    cout.write(sw,swsize);
    fclose(stdout);
    fprintf(stderr,"Test: (write, %d ints, %d chars) %.2lfc + %.2lfc\n",N,swsize,(swtime+.0)/CLOCKS_PER_SEC,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_fwrite_int() {
    int cur=clock();
    freopen("temp.txt","w",stdout);
    fwrite(sw,1,swsize,stdout);
    fclose(stdout);
    fprintf(stderr,"Test: (fwrite, %d ints, %d chars) %.2lfc + %.2lfc\n",N,swsize,(swtime+.0)/CLOCKS_PER_SEC,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_scanf_int() {
    int cur=clock();
    freopen("temp.txt","r",stdin);
    for (int i=0;i<N;i++) {
        int t;
        scanf("%d",&t);
        if (t!=a[i]) {
            fprintf(stderr,"Fail with scanf\n");
            exit(1);
        }
    }
    fclose(stdin);
    fprintf(stderr,"Test: (scanf, %d ints) %.2lfc\n",N,(clock()-cur+.0)/CLOCKS_PER_SEC);
}

// Part of iq.opengenus.org
void test_cin_int() {
    int cur=clock();
    freopen("temp.txt","r",stdin);
    for (int i=0;i<N;i++) {
        int t;
        cin >> t;
        if (t!=a[i]) {
            fprintf(stderr,"Fail with cin\n");
            exit(1);
        }
    }
    fclose(stdin);
    fprintf(stderr,"Test: (cin, %d ints) %.2lfc\n",N,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_printf_char() {
    int cur=clock();
    freopen("temp.txt","w",stdout);
    for (int i=0;i<NC;i++)
        printf("%c",s[i]);
    fclose(stdout);
    fprintf(stderr,"Test: (printf, %d chars) %.2lfc\n",NC,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_cout_char() {
    int cur=clock();
    freopen("temp.txt","w",stdout);
    for (int i=0;i<NC;i++)
        cout << s[i];
    fclose(stdout);
    fprintf(stderr,"Test: (cout, %d chars) %.2lfc\n",NC,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_putchar_char() {
    int cur=clock();
    freopen("temp.txt","w",stdout);
    for (int i=0;i<NC;i++)
        putchar(s[i]);
    fclose(stdout);
    fprintf(stderr,"Test: (putchar, %d chars) %.2lfc\n",NC,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_scanf_char() {
    int cur=clock();
    freopen("temp.txt","r",stdin);
    for (int i=0;i<NC;i++) {
        char t;
        scanf("%c",&t);
        if (t!=s[i]) {
            fprintf(stderr,"Fail with scanf\n");
            exit(1);
        }
    }
    fclose(stdin);
    fprintf(stderr,"Test: (scanf, %d chars) %.2lfc\n",NC,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_cin_char() {
    int cur=clock();
    freopen("temp.txt","r",stdin);
    for (int i=0;i<NC;i++) {
        char t;
        cin >> t;
        if (t!=s[i]) {
            fprintf(stderr,"Fail with cin\n");
            exit(1);
        }
    }
    fclose(stdin);
    fprintf(stderr,"Test: (cin, %d chars) %.2lfc\n",NC,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_getchar_char() {
    int cur=clock();
    freopen("temp.txt","r",stdin);
    for (int i=0;i<NC;i++) {
        char t=getchar();
        if (t!=s[i]) {
            fprintf(stderr,"Fail with getchar\n");
            exit(1);
        }
    }
    fclose(stdin);
    fprintf(stderr,"Test: (getchar, %d chars) %.2lfc\n",NC,(clock()-cur+.0)/CLOCKS_PER_SEC);
}
 
void test_read_char() {
    int cur=clock();
    freopen("temp.txt","r",stdin);
    cin.read(sw,NC);
    fclose(stdin);
    int cur2=clock();
    for (int i=0;i<NC;i++)
        if (s[i]!=sw[i]) {
            cerr << i << ' ' << (int)s[i] << ' ' << (int)sw[i] << endl;
            fprintf(stderr,"Fail with read\n");
            exit(1);
        }
    fprintf(stderr,"Test: (read, %d chars) %.2lfc + %.2lfc\n",NC,(cur2-cur+.0)/CLOCKS_PER_SEC,(clock()-cur2+.0)/CLOCKS_PER_SEC);
}
 
void test_fread_char() {
    int cur=clock();
    freopen("temp.txt","r",stdin);
    fread(sw,1,NC,stdin);
    fclose(stdin);
    int cur2=clock();
    for (int i=0;i<NC;i++)
        if (s[i]!=sw[i]) {
            fprintf(stderr,"Fail with fread\n");
            exit(1);
        }
    fprintf(stderr,"Test: (fread, %d chars) %.2lfc + %.2lfc\n",NC,(cur2-cur+.0)/CLOCKS_PER_SEC,(clock()-cur2+.0)/CLOCKS_PER_SEC);
}
 
int main () {
    gen();
    test_printf_int();
    test_cout_int();
    test_write_int();
    test_scanf_int();
    test_fwrite_int();
    test_cin_int();
    test_printf_char();
    test_scanf_char();
    test_cout_char();
    test_cin_char();
    test_putchar_char();
    test_getchar_char();
    test_read_char();
    test_fread_char();
}

Use ios_base::sync_with_stdio

Add the following code line at the top of your C++ program:

ios_base::sync_with_stdio(false);

This allows the interleaving between iostream and stdio functions and use the same stream. This enables iostream to work efficiently.

cin and cout

cin and cout are the slowest I/O functions so should be avoided. If used, add the following code line:

cin.tie(NULL);

This allows cout to be untied from cin. This results in cout being flushed before cin. In interactive programs, this should be avoided and flush should be added after each cin and cout.

Avoid use of endl

Avoid use of endl.

This is because when endl is used it outputs a new line after flushing the stream buffer which is an expensive operation. Use "\n" instead of endl.

Conclusion

The conclusion is:

  • For integer input, use scanf and for character input, use read.
  • For both integer and character output, use printf.
  • Add ios_base::sync_with_stdio(false); in your code.
  • Add cin.tie(NULL); in your code.
  • Use "\n" instead of endl.

With this article at OpenGenus, you must have the complete idea of how to optimize input and output I/O functions in C++.

Geoffrey Ziskovin

Geoffrey Ziskovin

Geoffrey Ziskovin is an American Software Developer and Author with an experience of over 30 years. He started his career with Haskell and has interviewed over 700 candidates for Fortune 500 companies

Read More

Improved & Reviewed by:


OpenGenus Foundation OpenGenus Foundation
Optimized Input Output I/O in C++
Share this