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

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

拿掉之后会快很多。

结果:
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<<'\n';
}

综合一下:

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

最后会优化到比肩scanf 和 printf

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

cin cout 的优化(神优化)外号:神读入的更多相关文章

  1. spark优化之优化数据结构

    概序: 要减少内存的消耗,除了使用高效的序列化类库以外,还有一个很重要的事情,就是优化数据结构.从而避免Java语法特性中所导致的额外内存的开销,比如基于指针的Java数据结构,以及包装类型. 有一个 ...

  2. acdream B - 郭式树 (水题 卡cin,cout, 卡LL)

    题目 输入正好是long long的最大, 但是答案超long long 所以用unsigned, 不能用cin cout否则一定超时: 不能用abs(), abs 只用于整数. unsigned   ...

  3. c/c++性能优化--- cache优化的一点杂谈

    之前写了一篇关于c/c++优化的一点建议,被各种拍砖和吐槽,有赞成的有反对的,还有中立的,网友对那篇博客的的评论和吐槽,我一个都没有删掉,包括一些具有攻击性的言论.笔者有幸阅读过IBM某个项目的框架代 ...

  4. printf scanf cin cout的区别与特征

    printf和scanf是c语言的输入输出,学习c++以后,自然是用cin cout这两个更简单的输入输出 printf scanf 都需要进行格式控制,比较麻烦,但优点是速度比较快,毕竟多做了一些事 ...

  5. [原]Android开发优化-Adapter优化

    ListView作为Android开发中使用频率最高的一个控件,保证ListView的流畅运行,对用户体验的提高至关重要.Adapter是ListView和数据源之间的中间人,当每条数据进入可见区时, ...

  6. SqlServer 数据库引擎优化顾问优化数据库

    现在一直在做的项目,数据量相对也不小,开始的时候没有觉得,因为是刚开始,数据量还很小,在程序使用过程中速度还挺快,但是随着数据量的不停的增长,发现程序越来越慢,甚至出现了超时的问题,因此要对程序和数据 ...

  7. Mysql优化之优化工具profiling

    程序员的成长之路 2016-11-23 22:42 Mysql优化之优化工具profiling 前言 mysql优化技术: mysql优化不是做一个操作就可以的优化,它包含很多的细节,需要一点一点的优 ...

  8. QRowTable表格控件(四)-效率优化之-优化数据源

    目录 一.开心一刻 二.问题分析 三.重写数据源 1.自己存储数据 2.重写data接口 四.比较 五.相关文章 原文链接:QRowTable表格控件(四)-效率优化之-优化数据源 一.开心一刻 一程 ...

  9. C++输入输出流 cin/cout 及格式化输出简介

    C++ 可通过流的概念进行程序与外界环境( 用户.文件等 )之间的交互.流是一种将数据自源( source )推送至目的地( destination )的管道.在 C++ 中,与标准输入/输出相关的流 ...

随机推荐

  1. 详解SpringBoot(2.3)应用制作Docker镜像(官方方案)

    关于<SpringBoot-2.3容器化技术>系列 <SpringBoot-2.3容器化技术>系列,旨在和大家一起学习实践2.3版本带来的最新容器化技术,让咱们的Java应用更 ...

  2. linux中c多线程同步方法

    https://blog.csdn.net/jkx01whg/article/details/78119189 Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥 ...

  3. AntD框架的upload组件上传图片时使用customRequest方法自定义上传行为

    本次做后台管理系统,采用的是 AntD 框架.涉及到图片的上传,用的是AntD的 upload 组件. 我在上一篇文章<AntD框架的upload组件上传图片时使用customRequest方法 ...

  4. 局域网访问电脑中VMware虚拟机

    场景 你在自己的台式机或笔记本中使用VMware Workstation搭建了一个虚拟机系统,如Debian.Fedora等Linux系统.现在你希望使用局域网中另一台电脑访问你电脑上的虚拟机系统,怎 ...

  5. Git Commit 提交规范

    写好 Commit message 好处多多: 1.统一团队Git commit 日志风格 2.方便日后 Reviewing Code 3.帮助我们写好 Changelog 4.能很好的提升项目整体质 ...

  6. 当小程序的flex布局遇到button时,justify-content不起作用的原因及解决方案

    当小程序的flex布局遇到button时 发现justify-content不起作用,无论怎么设置都是space-around的效果. 经过排查,发现原因是小程序button中的默认样式中的margi ...

  7. Docker镜像与容器的常用操作

    Docker镜像加速配置:Docker镜像常用操作:Dcoker容器常用操作. 镜像加速器 国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器.国内很多云服务商都提供了国内加 ...

  8. dB是乘以10还是乘以20

    dB即分贝(decibel),经常用来表示信号的大小.然而,今天在学习计算机网络的时候发现分贝的公式有两种:10lg(X) 或者 20lg(X) 很迷惑所以查找资料.得到的结果是dB在表示功率的时候用 ...

  9. Java 源码刨析 - HashMap 底层实现原理是什么?JDK8 做了哪些优化?

    [基本结构] 在 JDK 1.7 中 HashMap 是以数组加链表的形式组成的: JDK 1.8 之后新增了红黑树的组成结构,当链表大于 8 并且容量大于 64 时,链表结构会转换成红黑树结构,它的 ...

  10. cb43a_c++_STL_算法_删除_(1)remove_remove_if

    cb43a_c++_STL_算法_删除_(1)remove_remove_ifremove()remove_if() 注意:1.并不是真正的删除,而是把后面的元素向前移动,覆盖被删除元素,元素个数并没 ...