C ++输入性能

我试图解决InterviewStreet上的一个问题。 过了一段时间后,我确定我实际上花费了大部分时间阅读输入内容。 这个特定的问题有很多输入,所以这有一定的意义。 没有道理的是,为什么不同的输入方法有不同的表现:

最初我有:

std::string command;
std::cin >> command;

更换它明显更快:

char command[5];
cin.ignore();
cin.read(command, 5);

重写所有使用scanf使其更快

char command;
scanf("get_%c", &command);

所有人都告诉我,将阅读输入的时间减少了大约1/3。

我想知道这些不同的方法之间在性能上有这样的差异。 另外,我想知道为什么使用gprof没有强调我花在I / O上的时间,而是似乎指责我的算法。


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

它的功能(Unix shell)的代码是用C语言编写的,可以直接从stdin设备读取,而且效率很高。


冒着被低估的风险,I / O流通常比C对手更慢更庞大。 这不是避免使用它们的原因,因为它们更安全(曾经碰到过scanf或printf错误?不是很愉快),更通用(例如:重载插入运算符允许输出用户定义的类型)。 但我也会说,这不是在非常关键的代码中以教条形式使用它们的原因。

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

char command[5];
cin.ignore();
cin.read(command, 5);

原因:不需要内存分配,直接读取字符缓冲区。 在下面的C代码示例中也是如此,但是,即使在概念层面上调用scanf重复读取单个字符也无法达到最佳效果,因为scanf必须解析每次传递的格式字符串。 我会对你的I / O代码的细节感兴趣,因为当scanf调用读取单个字符变得最快时,发生错误的可能性似乎是合理的。 我只需要提问并且没有意义冒犯,但是代码是否真正编译并与优化有关?

至于你的第一个例子:

std::string command;
std::cin >> command;

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

至于gprof的细节,应该强调这些问题。 您是在看完整通话图表而不是平面图表吗? 在这种情况下,平面轮廓自然会产生误导。 我必须了解一些关于如何使用gprof来给出更好的答案的更多细节。


gprof只在CPU时间采样,而不是在阻塞时间。 所以,一个程序可能花一个小时做I / O,一个微秒做计算,而gprof只会看到微秒。

出于某种原因,这不是众所周知的。

链接地址: http://www.djcxy.com/p/57303.html

上一篇: C++ Input Performance

下一篇: Should [super loadView] be called from loadView or not?