一、sync_with_stdio()

这个函数是一个“是否兼容stdio”的开关,C++为了兼容C,保证程序在使用了std::printf和std::cout的时候不发生混乱,将输出流绑在了一起。 在IO之前将stdio接触绑定,可以大大提高IO效率。在操作大数据时,cin,cout的速率也能很快了。现在,我们通过比较解除绑定前后cin,printf的速率来实际体验下sync_with_stdio()的作用。首先,我们先产生1000万个随机数作为测试数据。然后,分别用cin,scanf来读取数据,比较其效率

  • data.cpp,产生1000万个随机数存贮在data.txt中,大概55M左右
/* 
本程序实现的功能: 
生成1000万个可能重复的随机数,用作测试数据  
并计算生成这些数据所用的时间  
*/  
#include <iostream>  
#include <ctime>   
using namespace std;  
#define SELF_RAND_MAX 0x7FFFFFFF  
int main()  
{  
 
    clock_t start_time = clock(); 
   
    srand(unsigned(time(0))); 
   
    const int MAX = 10000000;  
    const int MIN = 1000;  

    freopen("data.txt","w",stdout);  
 
    for(int i = 0; i < 10000000; ++i){   
        unsigned long data = rand() % (MAX - MIN + 1) + MIN; 
        cout << data << ' ';  
    }  
    fclose(stdout);  
    freopen("time.txt","w",stdout);  
    cout << endl   
         << "---the end---"   
         << endl;  
    //CLOCKS_PER_SEC控制精度,在windows环境下是1000,linux下是多少?  
    //简单地说windows下是毫秒级,而linux下好像是纳秒级   
    cout << "elapsed time:" << double(clock() - start_time) / CLOCKS_PER_SEC  
         << 's' << endl;  
      fclose(stdout);  
}
  • test.cpp, 测试程序,读取data.txt中的数据,比较cin, printf的效率
#include <iostream>
#include <ctime>
using namespace std;

void scanf_read();
void cin_read();

const int MAXIN = 10000000;
int numbers[MAXIN];

int main () {
    iostream::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    clock_t start_time = clock();
    //do something
    scanf_read();
    //cin_read();
    cout << "read time:"
         << double(clock() - start_time) / CLOCKS_PER_SEC
         << endl;
}

void scanf_read() {
    freopen("data.txt","r",stdin);
    for (int i = 0; i < MAXIN; ++i) {
        scanf("%d", &numbers[i]);
    }
}


void cin_read() {
    freopen("data.txt", "r", stdin);
    for (int i = 0; i < MAXIN; ++i)  {
        cin >> numbers[i];
    }
}

运行结果(win7 32 i3处理器,mingw 4.9.2):

  • 解除绑定前

    通过scanf来读取1000万个随机数需要的时间:16.323s

    通过cin来读取1000万个随机数需要的时间:24.361s

     我们可以看到,cin的读取时间整整比scanf满了8秒。

  • 解除绑定后

    通过scanf读取1000万个数据需要的时间:16.29s。

    通过cin来读取1000万个随机数需要的时间:4.946s,我们看到cin的读取时间整整缩短了20秒,比scanf的读取时间还快乐10秒。

  • 解除绑定,并cin.tie(nullptr), cout.tie(nullptr)

     通过cin来读取1000万个随机数需要的时间:4.861s,数值上来看,比只解除绑定好像快了一丢丢。但效果不明显。这里提到了tie()函数,下面就来看看tie()函数。

二、tie()

    tie()用来绑定stream,空参数则返回当前的输出流指针。

    直接上程序,看看其是如何表现的。

  • tie.cpp, 测试tie的实现效果。
#include <iostream>
#include <fstream>
using namespace std;

int main () {
    ostream *prevstr;
    ofstream ofs;

    ofs.open("test.txt");
    cout << "Output to the screen" << endl;
    
    *cin.tie() << "Output to the screem, too" << endl;  //null parameters, return the default output stream, i.e. cout

    prevstr = cin.tie(&ofs);   // cin bind to ofs, and return the pre output stream, i.e. cout
    *cin.tie() << "Output to the file, test.txt" << endl;

    *cin.tie(prevstr) << "Output to the file, too";
    *cin.tie() << "Output to the screen, again";

    ofs.close();

    return 0;

}

运行结果(环境同一):

    控制台输出:

Output to the screen
Output to the screen, too
Output to the screen, again

  文件输出:   

sync_with_stdio(), tie()的应用之美_其他

     对照程序结果,我们可以很清楚的明白tie()的作用。就不多讲了。