网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
06月24日漏签0天
图形编程forc吧 关注:14贴子:296
  • 看贴

  • 图片

  • 吧主推荐

  • 游戏

  • 52回复贴,共1页
<<返回图形编程forc吧
>0< 加载中...

控制台文本输出速度对比,结果让人无语。

  • 只看楼主
  • 收藏

  • 回复
  • hellovfp
  • 排序查找
    6
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
//测试代码:
#define CNT 3000
void test_console()
{
String s(L"I love my syster forevey!!!\n");
std::string s1("I love my syster forevey!!!\n");
double time1, time2, time3;
Clocker clock;
for(int i = 0; i < CNT; ++i)
puts("I love my syster forevey!!!");
time1 = clock.elapse();
clock.restart();
for(int i = 0; i < CNT; ++i)
console << s;
time2 = clock.elapse();
clock.restart();
for(int i = 0; i < CNT; ++i)
std::cout << s1;
time3 = clock.elapse();
printf("puts use %.3f\n", time1);
printf("write use %.3f\n", time2);
printf("std::cout use %.3f\n", time3);
}
测试C库的puts,和win32 API writeConsole,以及C++ 的cout输出同一个字符串3000次,在i5-5200(2.20GHZ)
本本+VS2010的测试结果:

如上图所示,结果是API的速度快得让人无语,最慢的C++的cout,打算重写控制台输出库了。


  • aaaaaaa421
  • 随机贪心
    13
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
我在你的代码上稍作修改,测试得到了一个奇怪的结果: cout(无同步) 比直接调用 API 都快,见图:

当然,我更好奇的是为什么 puts 会比 cout 慢,毕竟 puts 不像 printf 那样复杂,应该很快才对。


2025-06-24 12:19:41
广告
  • hellovfp
  • 排序查找
    6
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
大至以前也使用过C#,当时在垃圾的机器上运行控制台的输出程序,除了程序启运瞬间比较慢的话,感觉中间的输出可是比C的printf, puts快了很多,当时觉得挺神奇的,还以为是语言的不同造成的,结果无意中的这个测试,解释了心中的疑惑。Java底层其实也是直接调用Win32 API,不过由于本身语言的效率,感觉没有C#明显。
如果不考虑同步问题,我们得到的结果依然是C++的cout执行最慢。puts的效率,从mscrt源代码上来看,puts是调用_fwrite_lk 这个函数实现的,看着这么长的一段代码,能快多少?
/* define the normal version */
#ifdef _MT
size_t __cdecl _fwrite_lk (
#else /* _MT */
size_t __cdecl fwrite (
#endif /* _MT */
const void *buffer,
size_t size,
size_t num,
FILE *stream
)
{
const char *data; /* point to where data comes from next */
unsigned total; /* total bytes to write */
unsigned count; /* num bytes left to write */
unsigned bufsize; /* size of stream buffer */
unsigned nbytes; /* number of bytes to write now */
unsigned nwritten; /* number of bytes written */
int c; /* a temp char */
/* initialize local vars */
data = buffer;
count = total = size * num;
if (0 == count)
return 0;
if (anybuf(stream))
/* already has buffer, use its size */
bufsize = stream->_bufsiz;
else
#if defined (_M_M68K) || defined (_M_MPPC)
/* assume will get BUFSIZ buffer */
bufsize = BUFSIZ;
#else /* defined (_M_M68K) || defined (_M_MPPC) */
/* assume will get _INTERNAL_BUFSIZ buffer */
bufsize = _INTERNAL_BUFSIZ;
#endif /* defined (_M_M68K) || defined (_M_MPPC) */
/* here is the main loop -- we go through here until we're done */
while (count != 0) {
/* if the buffer is big and has room, copy data to buffer */
if (bigbuf(stream) && stream->_cnt != 0) {
/* how much do we want? */
nbytes = (count < (unsigned)stream->_cnt) ? count : stream->_cnt;
memcpy(stream->_ptr, data, nbytes);
/* update stream and amt of data written */
count -= nbytes;
stream->_cnt -= nbytes;
stream->_ptr += nbytes;
data += nbytes;
}
else if (count >= bufsize) {
/* If we have more than bufsize chars to write, write
data by calling write with an integral number of
bufsiz blocks. If we reach here and we have a big
buffer, it must be full so _flush it. */
if (bigbuf(stream)) {
if (_flush(stream)) {
/* error, stream flags set -- we're out
of here */
return (total - count) / size;
}
}
/* calc chars to read -- (count/bufsize) * bufsize */
nbytes = ( bufsize ? (count - count % bufsize) :
count );
nwritten = _write(_fileno(stream), data, nbytes);
if (nwritten == (unsigned)EOF) {
/* error -- out of here */
stream->_flag |= _IOERR;
return (total - count) / size;
}
/* update count and data to reflect write */
count -= nwritten;
data += nwritten;
if (nwritten < nbytes) {
/* error -- out of here */
stream->_flag |= _IOERR;
return (total - count) / size;
}
}
else {
/* buffer full and not enough chars to do direct write,
so do a _flsbuf. */
c = *data; /* _flsbuf write one char, this is it */
if (_flsbuf(c, stream) == EOF) {
/* error or eof, stream flags set by _flsbuf */
return (total - count) / size;
}
/* _flsbuf wrote a char -- update count */
++data;
--count;
/* update buffer size */
bufsize = stream->_bufsiz > 0 ? stream->_bufsiz : 1;
}
}
/* we finished successfully, so just return num */
return num;
}
printf内部也是经过多次调用,只是打印字符串的话,实际只是执行了下面类似的代码,然后再执行puts,哈哈,基本上能想到想应的结果。
while(*fmt)
{
if(*fmt != 0x25)//%
{
this->push_back(*fmt++);
continue;
}


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 52回复贴,共1页
<<返回图形编程forc吧
分享到:
©2025 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示