我想比较使用Python和C++从stdin读取字符串的读取行,并且看到我的C++代码运行速度比等效的Python代码慢一个数量级,这让我很震惊.由于我的C++生锈了,我还不是专家Pythonista,请告诉我,如果我做错了什么或者我是否误解了什么.
(TLDR回答:包括声明:cin.sync_with_stdio(false)或者只是fgets改用.
TLDR结果:一直向下滚动到我的问题的底部并查看表格.)
C++代码:
#include <iostream>
#include <time.h>
using namespace std;
int main() {
string input_line;
long line_count = 0;
time_t start = time(NULL);
int sec;
int lps;
while (cin) {
getline(cin, input_line);
if (!cin.eof())
line_count++;
};
sec = (int) time(NULL) - start;
cerr << "Read " << line_count << " lines in " << sec << " seconds.";
if (sec > 0) {
lps = line_count / sec;
cerr << " LPS: " << lps …Run Code Online (Sandbox Code Playgroud) 我刚刚在这个答案中发现了一条评论说iostream::eof在循环条件下使用"几乎肯定是错误的".我通常使用类似的东西while(cin>>n)- 我猜是隐式检查EOF,为什么检查eof显式使用while (!cin.eof())错误?
它与scanf("...",...)!=EOF在C中使用有何不同(我经常使用没有问题)?
许多C++书籍都包含这样的示例代码......
std::cout << "Test line" << std::endl;
Run Code Online (Sandbox Code Playgroud)
......所以我也一直这样做.但我已经看到很多来自像这样的开发人员的代码:
std::cout << "Test line\n";
Run Code Online (Sandbox Code Playgroud)
是否有技术上的理由偏爱另一个,或者仅仅是编码风格的问题?
所以我已经得到了我最后一个问题的答案(我不知道为什么我没有想到这一点).当我没想到它的时候,我正在打印一个圆润的double使用cout.如何使用全精度cout打印double?
我正在用C++编写一个小矩阵库来进行矩阵运算.然而,我的编译器抱怨,在它之前没有.这个代码留在架子上6个月,在我之间我将我的计算机从debian etch升级到lenny(g ++(Debian 4.3.2-1.1)4.3.2)然而我在具有相同g ++的Ubuntu系统上遇到了同样的问题.
这是我的矩阵类的相关部分:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
}
}
Run Code Online (Sandbox Code Playgroud)
而"实施":
using namespace Math;
std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {
[...]
}
Run Code Online (Sandbox Code Playgroud)
这是编译器给出的错误:
matrix.cpp:459:错误:'std :: ostream&Math :: Matrix :: operator <<(std :: ostream&,const Math :: Matrix&)'必须只取一个参数
我对这个错误感到有些困惑,但是在6个月里做了大量的Java后,我的C++又变得有点生疏了.:-)
我正在学习关于操作系统的大学课程,我们正在学习如何从二进制转换为十六进制,十进制到十六进制等等.今天我们刚刚学习了如何使用二进制补码(〜数字)将有符号/无符号数存储在内存中+ 1).
我们在纸上做了几个练习,我希望能够在向老师提交作业之前验证我的答案.我为前几个练习编写了一个C++程序,但现在我不知道如何通过以下问题验证我的答案:
char a, b;
short c;
a = -58;
c = -315;
b = a >> 3;
Run Code Online (Sandbox Code Playgroud)
我们需要在内存中显示二进制表示a,b和c.
我已经在纸上完成了它,它给了我以下结果(在二进制补码后的数字内存中的所有二进制表示):
a = 00111010(它是一个字符,所以1个字节)
b = 00001000(它是一个字符,所以1个字节)
c = 11111110 11000101(它是一个短的,所以2个字节)
有没有办法验证我的答案?在C++中是否有一种标准方法可以在数字的内存中显示二进制表示,或者我是否必须自己编写每个步骤(计算二进制补码然后转换为二进制)?我知道后者不会花那么长时间,但我很好奇是否有一种标准的方法可以做到这一点.
每当我提到C++标准库iostream的慢性能时,我都会遇到一阵难以置信的风潮.然而,我有剖析器结果显示在iostream库代码中花费了大量时间(完全编译器优化),并且从iostream切换到特定于操作系统的I/O API和自定义缓冲区管理确实提供了一个数量级的改进.
C++标准库做了多少额外工作,标准是否需要它,它在实践中是否有用?或者有些编译器提供了与手动缓冲区管理竞争的iostream实现吗?
为了解决问题,我编写了几个简短的程序来练习iostreams内部缓冲:
ostringstream http://ideone.com/2PPYwchar[]缓冲区http://ideone.com/Ni5ctvector<char>使用http://ideone.com/Mj2Fi将二进制数据放入其中back_inserter vector<char>简单的迭代器http://ideone.com/9iitvstringbuf http://ideone.com/qc9QAvector<char>简单的迭代器加边界检查http://ideone.com/YyrKy请注意,ostringstream和stringbuf版本运行的迭代次数较少,因为它们的速度要慢得多.
在ideone上,它ostringstream比std:copy+ back_inserter+ 慢大约3倍std::vector,比memcpy原始缓冲区慢大约15倍.当我将实际应用程序切换到自定义缓冲时,这与前后分析一致.
这些都是内存缓冲区,因此iostream的缓慢不能归咎于缓慢的磁盘I/O,过多的刷新,与stdio的同步,或者人们用来解释C++标准库观察到的缓慢的任何其他事情iostream的.
很高兴看到其他系统上的基准测试和常见实现的评论(例如gcc的libc ++,Visual C++,Intel C++)以及标准规定了多少开销.
许多人都正确地指出,iostream更常用于格式化输出.但是,它们也是C++标准提供的二进制文件访问的唯一现代API.但是对内部缓冲进行性能测试的真正原因适用于典型的格式化I/O:如果iostreams无法保持磁盘控制器提供原始数据,那么当他们负责格式化时,他们怎么可能跟上呢?
所有这些都是outer(k)循环的每次迭代.
在ideone上(gcc-4.3.4,未知的操作系统和硬件):
ostringstream:53毫秒stringbuf:27毫秒vector<char>并且back_inserter:17.6毫秒vector<char> 与普通迭代器:10.6毫秒vector<char> 迭代器和边界检查:11.4 mschar[]:3.7毫秒在我的笔记本电脑上(Visual C++ 2010 x86,cl …
我知道流是字节序列的表示.每个流提供了读取和写入其给定后备存储的字节的方法.但是流的重点是什么?为什么支持商店本身不与我们互动?
无论出于何种原因,这个概念都不是为了点击我.我读了很多文章,但我想我需要一个比喻或类似的东西.
首先,似乎我在征求主观意见,但这并不是我所追求的。我很想听听有关该主题的一些有充分根据的论点。
为了对如何设计现代流/序列化框架有所了解,我最近得到了Angelika Langer和Klaus Kreft撰写的《Standard C ++ IOStreams and Locales》一书的副本。我发现,如果IOStreams的设计不当,那么它就不会首先进入C ++标准库。
在阅读了本书的各个部分之后,我开始怀疑IOStreams是否可以从整体架构的角度与STL进行比较。阅读例如对Alexander Stepanov(STL的“发明人”)的采访,以了解有关STL的一些设计决策。
特别令我惊讶的是:
谁来负责IOStreams的总体设计似乎是个未知数(我很想阅读有关此的一些背景信息-有人知道好的资源吗?);
一旦你钻研输入输出流,例如眼前表面之下,如果你想输入输出流用自己的类扩展,你会得到一个接口具有相当神秘和扑朔迷离的成员函数的名称,例如getloc/ imbue,uflow/ underflow,snextc/ sbumpc/ sgetc/ sgetn,pbase/ pptr/ epptr(和有可能甚至更糟的例子)。这使得了解整体设计以及单个零件如何协作变得更加困难。即使我上面提到的那本书没有帮助那多(恕我直言)
因此,我的问题是:
如果你要判断今天的软件工程标准(如果确实是对这些任何普遍同意),将C ++的输入输出流仍然被认为是经过精心设计?(我不想通过通常认为过时的方法来提高软件设计技能。)
iostream ×10
c++ ×9
c++-faq ×2
cout ×2
.net ×1
benchmarking ×1
binary ×1
coding-style ×1
getline ×1
java ×1
namespaces ×1
ostream ×1
performance ×1
precision ×1
printf ×1
python ×1
std-bitset ×1
stdio ×1
stream ×1