printf大战cout

从二者底层看,前者可能用汇编实现的,后者用多重虚拟继承,前者编码应该比后者效率高很多。

从易用上看,显然后者方便些,而且容易继续重载和格式化输出。

从执行效率上看,输出整数时前者显然要快于后者,用我的机器测试输出10万个随机数前者耗费49秒,后者耗费53秒。输出文本时二者速度上几乎没有差异,我曾尝试输出一个32MB的文本文件(运行super pi计算到3355万位,大约38MB,再去掉空格大约32MB),全屏输出时printf耗费2566秒,cout耗费2554秒,输出几兆的小文本二者速度相差不超过一秒,内存消耗也基本差不多。

值得一提的是,很多情况下二者不能“兼容”,scanf读取的就用printf输出,cin读取的就用cout输出,和早期的C程序接口的用printf,后来的C++库函数和类接口的用cout输出,混用有时候会出现莫名其妙的结果,甚至不能正常响应。

printf和cout都用于屏幕输出,在时间要求严格内存也限制的场合我们不得不考虑它们二者的执行效率问题,到底哪个好用呢?


我们知道printf用于格式化输出很麻烦,因为要记忆那些格式很烦琐,而cout则不用顾虑这些,它知道要输出的类型。printf可以用于输出变参,一下子可以输出很多种类型,cout则只能一次一个。printf在底层可能是用汇编编写的源代码,而cout用C++语言的多重虚拟继承,从生成目标代码的执行效率上考虑,可能printf显然要快于cout,但是cout也不是吃素的,也进行了优化处理。


为此,实际测试一下看看吧,当输出数据少时是分不出胜负的,所以我特意运行super pi计算到小数点后大约3355万位生成一个文本文件,文件大小约38M字节,[super pi常用于测试电脑稳定性,我的电脑计算这么大一个浮点数耗费了1小时44分05秒,Windows自带的记事本,效率太低,无法打开这么大的文本,一打开就死,想起来就上火]为了方便又编写了一个小程序去掉所有的空格和换行符,这样生成的文件大约就剩32M字节了。然后分别用printf和cout对它进行输出,自动计算耗费的时间。


当最小化窗口时(程序在后台运行),printf和cout各用10秒完成全部输出,内存消耗也少得多,基本不分胜负!当最大化输出窗口全屏显示且输出字符数组时,printf耗费2566秒完成全部输出,而cout完成全部输出耗费了2554秒,时间上cout稍微胜出,但微乎其微。又测试了一次,这次printf输出没有使用字符数组,而直接调用sting的成员函数c_str(),耗时2606秒,cout耗时2556秒。所有测试过程中关闭屏幕保护程序,关闭其它程序,不移动鼠标,不碰键盘,做到尽量公平。


再看内存消耗上,全屏显示时,用printf时常占内存66996K,峰值66996K,虚拟内存98728K,用cout时常占内存33624K,峰值66996K,虚拟内存98728K,从内存消耗上cout要少一点。


所用机器配制为:IBM T23,PIII Mobile CPU,主频1.13GHz,内存SDRAM 512MB,彩显14'1,显卡S3,16MB的显存,硬盘40GB,虚拟内存设置成768MB。操作系统为Windows XP Professional Server Pack2,版本2002。

  
程序用GNU Dev-C++编译器编译的,源代码如下:

#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
#include <ctime>

using namespace std;

int main()
{
   cout<<"Enter file to read"<<endl;
   string filename;
   cout<<"Your file should be less than "<<filename.max_size()<<" character's!"<<'\n';
   /*文件大小不能超过1073741820个字符,也就是大约1GB。*/
   getline(cin,filename);//读取一个文本文件
   ifstream fin(filename.c_str());
   if(!fin.is_open())
   {
     cerr<<"cannot open file "<<filename<<'\n';
     return EXIT_FAILURE;
   }
   string str, line;
   while(getline(fin, line)) str += line, str += '\n';

   /*
   一次读取一行要比一个个字符的读取快很多倍,文件大时尤其明显。
   char ch = 0; while(fin.get(ch)) str += ch; 
   */

   *--str.end() = EOF;//文件结束符
   cout<<"characters in total: "<<str.size()<<" character(s)"<<'\n';//计算出了字符个数
   system("pause");
  
   char* buf = new char[str.size() + 1];
   strcpy(buf, str.c_str());
   long count = 0
   count = time(0);
   printf("%s", buf);
   printf("\n%d\n", time(0) - count);
   delete [] buf;
   system("pause");
   /* 
   count = time(0);
   printf("%s", str.c_str());
   printf("\n%d\n", time(0) - count);
   system("pause");
   */
   count = time(0);
   cout<<str;
   cout<<'\n'<<time(0) - count<<'\n';
   cout<<'\n';
   system("pause");

   return EXIT_SUCCESS;
}

从以上这个非常简单例子可以大致看出,算法对执行效率影响很大。


高级语言编写的cout速度仍然很快,很大程度上可能因为C++的string类和iostream类对字符窜的内存管理和输出进行了优化,所以大大提高了效率。


本文不是说cout与printf谁快谁慢,有的场合printf更快些,我尝试单纯的输出10万个整数,printf耗时49秒,cout耗时53秒。如果用我的机器全屏输出本文3000多个字符的话,printf和cout耗费时间都大约1秒。后又尝试了输出一个288808个字符的文本文件,结果都耗时44秒,再尝试输出一个460808个字符的文本文件,printf耗时77秒,cout耗时也77秒,在输出一文本554260字节大小,各耗时100秒,可见文本输出时二者速度上差距甚小,但是如果你想用来输出大批量整数(>10万)的话,printf可能显著快一点!

posted on 2013-05-13 15:12  woud  阅读(4241)  评论(0)    收藏  举报

导航