首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++输入性能

C++输入性能
EN

Stack Overflow用户
提问于 2012-02-02 00:03:16
回答 4查看 969关注 0票数 8

我在试着解决InterviewStreet上的一个问题。过了一段时间后,我确定我实际上花费了大部分时间来阅读输入。这个特定的问题有很多输入,所以这是有意义的。不合理的是为什么不同的输入方法会有如此不同的性能:

最初我有:

代码语言:javascript
复制
std::string command;
std::cin >> command;

替换它会让它变得更快:

代码语言:javascript
复制
char command[5];
cin.ignore();
cin.read(command, 5);

重写所有内容以使用scanf使其速度更快

代码语言:javascript
复制
char command;
scanf("get_%c", &command);

总而言之,我将阅读输入的时间减少了大约1/3。

我想知道这些不同的方法在性能上有这么大的差异。此外,我想知道为什么使用gprof没有突出我在I/O上花费的时间,而是似乎将责任指向我的算法。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-02-02 00:07:27

这些例程有很大的差异,因为控制台输入速度几乎不重要。

而且在它需要的地方(Unix shell),代码是用C语言编写的,直接从标准输入设备读取,而且效率很高。

票数 3
EN

Stack Overflow用户

发布于 2012-02-02 00:32:47

冒着被否决的风险,I/O流通常比它们的C对应物更慢、更大。这不是避免在许多目的中使用它们的理由,因为它们更安全(曾经遇到过scanf或printf错误吗?不是很友好)和更通用的(例如:重载插入操作符,允许您输出用户定义的类型)。但我也要说,这不是在对性能非常关键的代码中教条式地使用它们的理由。

不过,我确实发现结果有点令人惊讶。在你列出的三个中,我怀疑这是最快的:

代码语言:javascript
复制
char command[5];
cin.ignore();
cin.read(command, 5);

原因:不需要内存分配,直接读取字符缓冲区。下面的C示例也是如此,但是调用scanf来重复读取单个字符也不是最优的,即使在概念级别上也是如此,因为scanf必须解析每次传入的格式字符串。我会对你的I/O代码的细节感兴趣,因为当scanf调用读取单个字符被证明是最快的时候,发生错误的可能性是合理的。我只是想问一下,并没有冒犯的意思,但是代码真的编译并链接了优化吗?

现在来看你的第一个例子:

代码语言:javascript
复制
std::string command;
std::cin >> command;

我们可以预期这会比最优的慢得多,因为你正在使用一个可变大小的容器(std::string),这将不得不涉及到一些堆分配来读取所需的缓冲区。当涉及到堆栈与堆的问题时,堆栈总是要快得多,所以如果您可以预测在特定情况下所需的最大缓冲区大小,堆栈上的一个简单的字符缓冲区将击败std::string进行输入(即使您使用了reserve)。这同样适用于堆栈上的数组,而不是std::vector,但这些容器最适合于无法预先预测大小的情况。其中std::string可能更快的情况是,人们可能会尝试重复调用strlen,而存储和维护一个size变量会更好。

至于gprof的细节,它应该强调这些问题。您是否正在查看完整的调用图,而不是平面配置文件?当然,在这种情况下,扁平轮廓可能会产生误导。我必须了解更多关于如何使用gprof的细节才能给出更好的答案。

票数 1
EN

Stack Overflow用户

发布于 2012-02-02 05:37:02

gprof仅在CPU时间内采样,而不在阻塞时间内采样。因此,一个程序可能花一个小时做I/O,花一个微秒做计算和gprof will only see the microsecond

由于某些原因,这一点并不为人所知。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9099058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档