关于iostream的效率问题
前言
经常有人说iostream的速度慢,IO流比stdio的慢多了。但是有人测试过的,iostream的速度是超过stdio的。
测试结果
/* C */
#include <stdio.h>
int main()
{
FILE* stream;
size_t num;
size_t sum = 0;
size_t i = 0;
stream = fopen("random.data", "r");
while(fscanf(stream, "%u", &num) != EOF)
{
sum += num;
}
fclose(stream);
printf("%u\n", sum);
return 0;
}
/* C++ */
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream stream("random.data");
size_t num;
size_t sum = 0;
while(stream >> num)
{
sum += num;
}
cout << sum << endl;
return 0;
}
random.data中为100000个0-32767的随机数
C版本平均用时0.64s,C++平均用时0.58s
于是又把这陈芝麻烂谷子事拿出来研究。单步VC10/11(用后者是因为新版加入了chrono方便计时),cout输出一段字符串的调用顺序如下:
operator<< => sputn => xsputn => overflow => _Fputc => fputc
cout封装了fputc一个字符一个字符的输出,而Win下默认不给stdout开buffer,于是造成cout输出字符串极度缓慢,杯具出现了
想起线程安全性问题。cout虽然线程安全(原文:http://msdn.microsoft.com/en-us/library/c9ceah3b.aspx),但是输出的字符是混在一起的,我猜想也是cout封装fputc而在fputc里加锁的原因。
看printf()的源码:
va_start(arglist, format);
_lock_str2(1, stdout);
__try {
// int _stbuf(stream) - set temp buffer on stdout, stdprn, stderr
buffing = _stbuf(stdout);
retval = _output_l(stdout,format,NULL,arglist);
// void _ftbuf(flag, stream) - take temp buffering off a stream
_ftbuf(buffing, stdout);
}
__finally {
_unlock_str2(1, stdout);
}
首先将stdout整体加锁,然后给stdout开了一个临时buffer,输出后再刷新,显然要比cout快得多。
测试用了fstream,文件指针在win下是默认开buffer的,于是给cout手动开buffer,前后测试结果如下:
未开buffer:
开了buffer:
可以看到未开buffer时cout的用时比printf慢数十倍,开buffer后的用时与printf已经十分接近(cout绑定stdout,给cout开buffer就等于给printf开buffer),造成的差异应该是每个字符分别加锁的缘故。另外printf用%s输出比直接输出快,大概是因为直接输出的话解析格式字符串时每个字符都要判断format[n]=='%'
这是g++ MinGW-w64的测试结果:
未开buffer:
开了buffer:
stdlibc++使用了不同的封装方式,未开buffer时两者速度已经较为接近,开buffer后已经超过用printf直接输出。
关于g++和VC的速度比较,除了原生64位以外,CRT也有差距,毕竟VC是微软自己的东西
注:mingw的cout.rdbuf()->pubsetbuf似乎有问题,改用setvbuf
附虚拟机下Fedora 16(g++ 4.6.2)测试结果(linux默认给stdout开buffer)
TIP:
关于cout输出慢,可能是buffer刷新的问题 把endl换成'\n'就会快上许多了。
关于iostream的效率问题的更多相关文章
- Golang 效率初(粗)测
从接触 Golang 开始,断断续续已有差不多一年左右的时间了,都是业余自己学学看看,尚主要限于语法及语言特性,还没有用它写过实际的项目. 关于 Golang 的语法及语言特性,网上有很多资源可以学习 ...
- C++操作MySQL大量数据插入效率低下的解决方法
#include <iostream> #include <winsock2.h> #include <string> #include "mysql.h ...
- 测试lua的效率
这几天粗略的测试了一下lua的效率!首先声明这个测试很有针对性,大部分是针对游戏中的使用,而绝非lua的整体性效率(这个测试我不会),lua构建的上层逻辑中,大概使用的语句不太多,for,迭代,调用C ...
- include<stdio.h> 和include<iostream.h>的区别
stdio 是C标准库里面的函数库 对应的基本都是标准输入输出等等C语言常用库的定义iostream是C++标准库的头定义, 对应的基本上是C++的输入输出相关库定义开发C程序用Stdio, C++用 ...
- 基于OpenMP的矩阵乘法实现及效率提升分析
一. 矩阵乘法串行实现 例子选择两个1024*1024的矩阵相乘,根据矩阵乘法运算得到运算结果.其中,两个矩阵中的数为double类型,初值由随机数函数产生.代码如下: #include <i ...
- c++拼接字符串效率比较(+=、append、stringstream、sprintf)
转自:http://www.cnblogs.com/james6176/p/3222671.html c++拼接字符串效率比较(+=.append.stringstream.sprintf) 最近写的 ...
- iostream/fstream中的输入输出流指针的绑定,tie函数的使用。
为了兼容c语言的输入输出,c++里面采用tie将输入输出流经行绑定,所以cin/cout并不是独立的.当执行cin时,cout同时会被执行.反之亦然. by defalut,cin is tied ...
- Cin、Cout 加快效率方法
std::ios::sync_with_stdio(false); 在main 函数中加上这么一句话. 可以打消iostream的输入输出缓存,可以节省许多时间,使效率与scanf与printf相差无 ...
- CMap与hash_map效率对照
CMap与hash_map底层均採用hash stable实现,CMap是MFC提供的模板类.hash_map尽管眼下并未纳入C++标准模板类库,但差点儿每一个版本号的STL都提供了对应的实现.CMa ...
随机推荐
- Android中的PopupWindow的使用
PopupWindow 需要一个自定义的布局文件 列如:popupwindow.xml <?xml version="1.0" encoding="utf-8&qu ...
- Bonobos | IT桔子
Trumaker | IT桔子 Trumaker trumaker.com
- Java组合与继承生成的类中构造函数的执行顺序
[程序实例] import java.util.*; class Meal{ Meal() { System.out.println("Meal Constructor"); } ...
- [ES6] Function Params
1. Default Value of function param: The function displayTopicsPreview() raises an error on the very ...
- 世界最大射电望远镜(Arecibo)用于探測地外文明
请看下图: 这是眼下世界最大口径(305米)射电望远镜的外观图,位于美国中西部的PuertoRico州,建成于1963年,工作波段在3厘米至1米波段范围内,正好适合用于探測地外文明(SETI)的科学研 ...
- ViewPager切换动画PageTransformer使用
Android从3.0开始,就添加了很多动画,ViewPager当然也不例外,相对于非常平庸的默认切换动画,Google给我们展示了两个动画例子:DepthPageTransformer和ZoomOu ...
- css选择器基本属性
选择器一,相邻选择器: 1,相邻选择器 1),定义:相邻选择器匹配指定元素的相邻兄弟元素 2),用法:如果需要选择紧接在另一个元素后的元素,而且二者有相同的父元素,可以使用相邻兄弟选择器 3),表示符 ...
- border和outline区别
border和outline区别: border支持box-sizing: border-box,当有边距时,是新增了边框后在按照以前的边距处理 outline不支持box-sizing: borde ...
- IIS Express 终极玩法
进入正题之前,先吐嘈下微软的win10升级吧.之前有意不想将win 7 旗舰版(也是破解版哈)升到win 10,自从微软推出win10后,其本上对其没多大兴趣,感觉系统各种卡顿,各种不流畅,界面各种不 ...
- HTML5 Canvas图片操作简单实例1
1.加载显示图片 <canvas id="canvasOne" class="myCanvas" width="500" height ...