我已经告诉别人,编写using namespace std;代码是错误的,我应该用std::cout和std::cin直接代替.
为什么被using namespace std;认为是不好的做法?是低效还是冒着声明模糊变量(与名称std空间中的函数具有相同名称的变量)的风险?它会影响性能吗?
每当我提到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 …
我不知道这是不是真的,但当我在其中一个问题提供网站上阅读常见问题时,我找到了一些东西,引起了我的注意:
检查输入/输出方法.在C++中,使用cin和cout太慢了.使用这些,您将保证无法通过适当的输入或输出解决任何问题.请改用printf和scanf.
有人可以澄清一下吗?真的在C++程序中使用scanf()比使用cin更快吗?如果是,那么在C++程序中使用它是一个好习惯吗?我认为这是C特定的,虽然我只是学习C++ ...
自从我std::endl在写作时停止使用结束行std::cout并开始使用以来已经很多年了"\n".
但现在我开始看到更多的代码片段'\n',我开始想知道什么是最好的.
除了显而易见的是一个字符串,另一个字符,使用它有任何好处:
std::cout << variable << '\n';
Run Code Online (Sandbox Code Playgroud)
在此:
std::cout << variable << "\n";
Run Code Online (Sandbox Code Playgroud)
迟到:
当我问这个问题时,我似乎认为换行'\n'刷新了缓冲区.现在我知道这取决于.
默认情况下std::cin,绑定到旧的C stdin FILE*流,并std::cout绑定到stdout.新线上的冲洗来自这种搭售.默认情况下stdout,如果连接到终端,则进行行缓冲.这意味着新行将刷新其缓冲区.因此,当使用打印换行符std::cout时,将导致stdout刷新.
如果stdout未连接到的终端(例如,输出已经被重定向或用管道输送),或者如果之间的联系std::cout和stdout被打破,则换行符将不刷新任何东西.
有没有理由使用endl与cout当我可以只使用\n?我的C++书说要使用endl,但我不明白为什么.是\n不是广泛支持endl,或者我错过了什么?
我目前从一个向量写一组双打到一个文本文件,如下所示:
std::ofstream fout;
fout.open("vector.txt");
for (l = 0; l < vector.size(); l++)
fout << std::setprecision(10) << vector.at(l) << std::endl;
fout.close();
Run Code Online (Sandbox Code Playgroud)
但这需要花费大量时间才能完成.有没有更快或更有效的方法来做到这一点?我很乐意看到并学习它.
在进行了一些测试后,我发现它printf比它快得多cout.我知道它依赖于实现,但在我的Linux机器上printf速度提高了8倍.所以我的想法是混合两种打印方法:我想cout用于简单的打印,我打算printf用于生成大量输出(通常在循环中).只要在切换到其他方法之前不忘记刷新,我认为这样做是安全的:
cout << "Hello" << endl;
cout.flush();
for (int i=0; i<1000000; ++i) {
printf("World!\n");
}
fflush(stdout);
cout << "last line" << endl;
cout << flush;
Run Code Online (Sandbox Code Playgroud)
这样好吗?
更新:感谢所有宝贵的反馈.答案摘要:如果你想避免棘手的解决方案,只需简单地不使用endl,cout因为它会隐式刷新缓冲区.请"\n"改用.如果你产生大量输出会很有趣.
我见过使用矢量的代码,
vector<int>s;
s.push_back(11);
s.push_back(22);
s.push_back(33);
s.push_back(55);
for (vector<int>::iterator it = s.begin(); it!=s.end(); it++) {
cout << *it << endl;
}
Run Code Online (Sandbox Code Playgroud)
它是一样的
for (auto it = s.begin(); it != s.end(); it++) {
cout << *it << endl;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下使用auto关键字有多安全?如果矢量类型是float什么?string?
使用逗号分隔的参数包的最简单方法是什么std::ostream?
例:
template<typename... Args>
void doPrint(std::ostream& out, Args... args){
out << args...; // WRONG! What to write here?
}
// Usage:
int main(){
doPrint(std::cout,34,"bla",15); // Should print: 34,bla,15
}
Run Code Online (Sandbox Code Playgroud)
注意:可以假设<<操作员的相应过载可用于所有类型的参数包.
我是C++的新手,并且一直在学习这样的东西:
cout << "My age is: ";
cin >> age;
Run Code Online (Sandbox Code Playgroud)
和cin一起乱搞,我遇到了障碍.
说我想写"我已经x岁了!".
"x"是cin >>年龄;
我写这样的代码.
cout << "I am ";
cin >> age;
cout << "years old!";
Run Code Online (Sandbox Code Playgroud)
障碍是这会产生换行符.
我不希望换行.
我怎么能把这一切留在一条线上?