【C++实验】cout和printf的速度对比

【C++实验】cout和printf的速度对比
注:原来投的洛谷,但是投了 ∞ \infty ∞ 次也没过,原链接

输出,是一项很重要的事。一切信息学比赛以输出为基础,但高等级的 OI 输出太大,一不留神就 T L E \textcolor{#0000A1}{TLE} TLE。因此,我们要学习如何更快输出,毕竟没人愿意比赛因为输出过大而超时。

实验起因

洛谷有一种很少见的评测状态,叫 O L E \textcolor{#0000A1}{OLE} OLE。意思是输出超限。
举个 OLE 代码的栗子:

#include<bits/stdc++.h>usingnamespace std;intmain(){while(1){printf("555555555555555\n");}return0;}

毫无疑问,第一眼看到这段代码,会让人觉得会 TLE。但事实是,printf 太快,达不到 TLE 的等级,会在规定时间内输出很多东西,于是程序会被 OJ 强行终止并判定 OLE。

那么,为什么刚刚要用 printf 创造 OLE 呢?
我一开始信了 OI 界的一个广泛的说法: cout 效率比 printf 低。
其实 cout 也 OLE 了

但这只是传言,不一定是对的(对的,后面,我推翻了它)。
于是,我开始了一次实验。

实验设计

为了公平比较,保证所有测试均遵循以下条件:

  • 编译环境:使用 mingw64 的 g++ 编译 使用编译参数 -std=c++14 -O2 进行编译,这是竞赛的标准配置。
  • 计时方法:使用 C++11 的 chrono 库进行毫秒级计时,单组实验多次取平均值以减少误差。
  • 测试场景:涵盖标准输出、输出重定向到文件、直接使用文件流(ofstream) 三种典型情况。
  • 测试数据:从少量( 100 100 100 个)到大量( 1   000   000 1 \ 000 \ 000 1 000 000 个)递增,以观察不同数据规模下的表现。

实验过程

标准输入输出

标准输入输出流版本:

#include<iostream>#include<cstdio>#include<chrono>usingnamespace std;intmain(){auto program_start = std::chrono::high_resolution_clock::now();for(int i =0; i <100; i ++){ cout <<1;}auto program_end = std::chrono::high_resolution_clock::now();auto total_duration = std::chrono::duration_cast<std::chrono::milliseconds>(program_end - program_start); cout <<"time:"<< total_duration.count()<<"ms"<< endl;return0;}

输出:

11111111111111111111111111111······(后略) time:15ms 

cout << 1 换成 printf("1"); ,平均时间直接只剩10毫秒
多次数据证明:此时printf 较快。

文件读写

我们先看看文件重定向 +printf 的速度。

#include<iostream>#include<cstdio>#include<chrono>usingnamespace std;intmain(){auto program_start = std::chrono::high_resolution_clock::now();freopen("test.out","w",stdout);for(int i =0; i <100; i ++){printf("1");}auto program_end = std::chrono::high_resolution_clock::now();auto total_duration = std::chrono::duration_cast<std::chrono::milliseconds>(program_end - program_start); cout <<"time:"<< total_duration.count()<<"ms"<< std::endl;fclose(stdout);return0;}

输出:0ms

还有和标准流相对的文件流,也是相当著名的文件输入输出方法。

#include<fstream>#include<chrono>usingnamespace std;intmain(){auto program_start = std::chrono::high_resolution_clock::now(); ofstream fout("test.out");for(int i =0; i <100; i ++){ fout <<1;}auto program_end = std::chrono::high_resolution_clock::now();auto total_duration = std::chrono::duration_cast<std::chrono::milliseconds>(program_end - program_start); fout <<"time:"<< total_duration.count()<<"ms"<< std::endl;fclose(stdout);return0;}

输出:0ms

这些数据证明小规模文件操作和 std 相比还是很快的。

加大数据量

换成输出 100000 100000 100000 个 1 1 1:

#include<fstream>#include<chrono>usingnamespace std;intmain(){auto program_start = std::chrono::high_resolution_clock::now(); ofstream fout("test.out");for(int i =0; i <100000; i ++){ fout <<1;}auto program_end = std::chrono::high_resolution_clock::now();auto total_duration = std::chrono::duration_cast<std::chrono::milliseconds>(program_end - program_start); fout << endl<<"time:"<< total_duration.count()<<"ms"<< endl;fclose(stdout);return0;}

输出:

1111111111111111······(后略) time:1ms 
#include<iostream>#include<cstdio>#include<chrono>usingnamespace std;intmain(){auto program_start = std::chrono::high_resolution_clock::now();freopen("test.out","w",stdout);for(int i =0; i <100000; i ++){printf("1");}auto program_end = std::chrono::high_resolution_clock::now();auto total_duration = std::chrono::duration_cast<std::chrono::milliseconds>(program_end - program_start); cout << endl <<"time:"<< total_duration.count()<<"ms"<< std::endl;fclose(stdout);return0;}

输出:

1111111111111111······(后略) time:6ms 

时间依然很少,代表测试规模依然不够。

为了真正显现出两者速度的差别,我们加大数据,让它输出 10000000 10000000 10000000 个 1 1 1。

11111111111111111111······(后略) time:56ms 

这一次,即使是 printf 也花了 56 56 56 毫秒
测测 cout,结果竟是 27 27 27 毫秒

测了 10 次,最慢就是 27 毫秒。因此这个数据正式破除了一个言论:cout 永远比 printf 慢。事实证明,它在文件读写更胜一筹。

这次使用的是文件重定向,而文件流(fout)的表现则更让人惊讶:仅仅 16 毫秒

实验结论

数据分析

  • 在小数据量情况下,cout 确实慢于 printfcout 由于需要维护类型安全并可能与 C 标准流同步,其单次函数调用的开销略高于 printf
  • 在文件读写且中小数据量时,两者相差不多,因为重定向和文件流的缓冲区都够大,磁盘 IO 会在关闭文件时统一处理。
  • 在大规模文件读写时,coutfout 更大缓冲区的好处就出来了:真实磁盘 IO 次数少很多。因此它们相对缓冲区小且更保守的 printf 快。
  • cout 的输出在文件 IO 时还得重定向,fout 根本不用,缓冲区策略也激进,磁盘 IO 更少,所以在所有文件测试中都领先。

具体数据

数据具体如下表:

输出 1 的数量文件读写形式使用语句时间(取平均值)
100 个\cout<<1;15ms
100 个\printf("1");10ms
100 个文件重定向printf("1");0ms
100 个文件重定向cout << 1;0ms
100 个文件流fout << 1;0ms
100000 个文件重定向printf("1")6ms
100000 个文件重定向fout << 1;2ms
100000 个文件流fout << 1;1ms
1000000 个文件重定向printf("1");56ms
1000000 个文件重定向fout << 1;26ms
1000000 个文件流fout << 1;16ms

从以上数据可得出,对于标准输入输出,printf 更快;对于文件读写,经过优化的 cout 更胜一筹。

总之,对于常规 OJ 刷题,推荐 cout(求速度使用 ios::sync_with_stdio(false);,会关闭与C标准流的同步);对于需格式化输出的时候,iomanip 内的工具开销较大,所以推荐printf;正规比赛时,还得用 fout 等,重定向顺手但相对其较慢,而且有些比赛不让用

注意:使用 cout 时少用 std::endl ,会自动清空缓冲区,多一次 IO。

后记

之所以加大数据量中没测标准输入输出,是因为百万个 1不是能一下能输出完的,测不了。
局部由 Deepseek 优化。

之所以把 fout 拿来测,是因为觉得 fout 是 cout 在文件读写方面的优化。

Read more

耗时一周巨作——全面解析Coze工作流,实例搭建热门AI Agent

耗时一周巨作——全面解析Coze工作流,实例搭建热门AI Agent

我不是广告!! 个人主页-爱因斯晨 大家好呀!最近有没有想我?博主努力回三中哦! 近日,Coze开源引起科技圈激烈讨论。Coze开源是AI领域的重要举措,既通过Apache 2.0协议降低了智能体开发门槛,让开发者可自由部署、二次开发及商用,推动技术普惠与行业标准化,又能借助开源社区构建开发者生态,助力字节跳动推广豆包大模型和云服务,重塑行业竞争格局;但同时也面临功能生态短板(如缺失部分高级功能、插件较少)、可持续性风险(算力需求与变现压力)及安全治理挑战(漏洞风险与劣质应用泛滥)等问题,是一把兼具机遇与挑战的“双刃剑”。 一、初识Coze 1.价值定位 扣子空间是新一代AI Agent开发平台。凭借”低代码“功能,使开发门槛降低。开发的AI智能体,可以通过API或SDK将 AI 应用集成到你的业务系统中。提高了编码效率。 2.核心功能 一、智能体(Bot)构建核心功能 这是 Coze的基础且核心能力,

By Ne0inhk
OpenClaw(龙虾)开源AI智能体科普解析:核心原理、功能特性与本地部署教程

OpenClaw(龙虾)开源AI智能体科普解析:核心原理、功能特性与本地部署教程

近期开源AI领域,OpenClaw(俗称“龙虾”)凭借其本地优先、可定制的特性,受到开发者社区的广泛关注,其项目保活程度与社区活跃度可通过GitHub数据直观体现:目前该项目已获得222k stars、1.2k watching、42.3k forks,各项数据均处于开源AI智能体领域前列,足以证明其社区认可度与持续更新能力。作为一款开源AI智能体工具,它在办公自动化、系统辅助等场景具有实用价值,适合开发者了解和落地实践。 OpenClaw是一款开源的个人AI助手编排平台,采用TypeScript开发,目前在GitHub上拥有较高的关注度,其核心价值在于将大模型的推理能力与本地系统操作相结合,打破了传统AI助手“仅能交互、无法执行”的局限。本文将从技术科普角度,围绕OpenClaw的核心定义、功能特性、技术细节及本地部署步骤展开,帮助开发者全面了解这款工具的原理与使用方法。 对于ZEEKLOG的开发者群体而言,了解OpenClaw的技术架构与应用场景,既能拓展AI智能体的认知边界,也能将其应用于日常开发、办公场景,提升工作效率。 本文将从「核心定义、功能特性、技术细节、本地部署」

By Ne0inhk
爆火的OpenClaw到底是个啥?一文看透这只“AI龙虾”的真面目与暗坑

爆火的OpenClaw到底是个啥?一文看透这只“AI龙虾”的真面目与暗坑

目录 前言 一、OpenClaw是什么?——它不是“最强大脑”,而是一双“手” 二、它能干什么?为什么让这么多人兴奋? 2.1 拥有“全局记忆”,它能越来越懂你 2.2 从“被动回答”到“主动干活” 2.3 深度的本地控制权 三、滤镜碎裂:这只“龙虾”背后的四个深坑 3.1 第一个坑:灾难级的安全隐患(最致命) 3.2 第二个坑:极不稳定的“办事能力” 3.3 第三个坑:令人咋舌的“烧钱”速度 3.4 第四个坑:大厂为什么不做?

By Ne0inhk
学习AI必备基础知识

学习AI必备基础知识

前段时间,由于回家过年,躺在床上实在感觉无聊, 所以就在网上搜罗了相关资料,整理了学习内容,方便以后温故。 进来各种模型频繁迭代,好像光是闻着claude、gpt、deepseek、豆包这些模型升级的声音,就已经让我们热血澎湃。 但你真的了解他们吗?你知道如何用好他们吗? 如: * user prompt * system prompt * AI Agent * function calling * MCP * RAG * 上下文窗口 可能你零星的知道些皮毛,不过没关系,现在让我带着你深入学习一番。 大纲 * 一、什么是所谓的user prompt * 二、user prompt 和 system prompt * 1、 user prompt(用户提示词) * 2、 system prompt(系统提示词) * 三、AI Agent

By Ne0inhk