zoukankan      html  css  js  c++  java
  • cin cout 的优化(神优化)外号:神读入

    在比赛里,经常出现数据集超大造成 cin TLE的情况。这时候大部分人(包括原来我也是)认为这是cin的效率不及scanf的错,甚至还上升到C语言和C++语言的执行效率层面的无聊争论。其实像上文所说,这只是C++为了兼容而采取的保守措施。我们可以在IO之前将stdio解除绑定,这样做了之后要注意不要同时混用cout和printf之类。

    在默认的情况下cin绑定的是cout,每次执行 << 操作符的时候都要调用flush,这样会增加IO负担。可以通过tie(0)(0表示NULL)来解除cin与cout的绑定,进一步加快执行效率。

    优化1:sync_with_stdio 函数:和stdio同步

    #include <iostream>
    int main(){
        std::ios::sync_with_stdio(false);   
    }
    

    优化2:endl 和 flush 物件:cout的缓衝区优化

    什么是endl,他是一个定义好的物件,在cout上给cout换行用的,那他跟<<’ ’有什么差别呢?
    原来,cout用了一个类似优化的设计,叫作缓冲区(由作业系统实作),所有的输出都会先进到缓冲区裡,直到缓冲区满了才会清空缓冲区并把字串输出到stdout之类的输出串流,难怪没有跟stdout同步会出错。
    而当一般人写程式的时候,输出当然希望程式会把东西印到萤幕上,但是如果缓冲区还没满,我们就看不到结果了!
    怎么办呢?cout有一个物件叫作flush(用法跟endl一样),做的事情就是强迫清空缓冲区,并输出到串流。
    但是为什么平常初学C++的人都没有打过flush呢?原因有几个,一个是Windows8以前的Windows CMD会自动清空缓冲区(或是根本没有QAQ),另外一个主要的原因就是,其实endl就是<<’ ’<<flush;,对,endl就是换行加上flush,也就是说,如果我们用endl的话,就会强迫每个数字都清空缓冲区,累积一定量再一起输出对cout来说可以优化一些操作,而这样就破坏了这个优化了

    ios_base::sync_with_stdio(false);
    for(int i = 0; i < (int)1e7; i++){
        cout<<rand()<<'
    ';
    }
    

     拿掉之后会快很多。

    结果:
    2.65 s
    1.78 s
    1.73 s
    去掉了endl之后,cout的速度已经和printf差不多快了!整整快了12秒!
    原来效率就是在这种情况下不见的,那为什么要作endl这种物件呢?
    我们看看下面的实验。

    附注,其实printf也是有缓冲区的,只是他预设是到满了才会清空。平常在console可以看到输出是因为OS帮忙我们把缓冲区清掉了

    优化3:cin.tie(0):cin和cout绑定

    cin.tie(0);
    for(int i = 0; i < (int)1e7; i++){
        cin>>a;
        cout<<a+1<<'
    ';
    }
    

    综合一下:

    #include <iostream>
    int main() 
    {
        std::ios::sync_with_stdio(false);   
        std::cin.tie(0);    // IO
        cout<<'
    ';       
    }
    

     最后会优化到比肩scanf 和 printf

    希望大家谨慎使用,别考试给挂了。

  • 相关阅读:
    vue-element-admin 权限的添加
    vue 图标通过组件的方式引用步骤
    linux系统环境下配置vue项目运行环境
    5.5 卷积神经网络(LeNet)
    5.4 池化层
    5.3 多输入通道和多输出通道
    5.2 填充和步幅
    html && CSS
    P2827 [NOIP2016 提高组] 蚯蚓
    5.1 二维卷积层
  • 原文地址:https://www.cnblogs.com/DZN2004/p/13199840.html
Copyright © 2011-2022 走看看