我想比较使用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) 我已经尝试了几件事,
std::stringstream m;
m.empty();
m.clear();
Run Code Online (Sandbox Code Playgroud)
两者都不起作用.
每当我提到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 …
我正在研究一个简单的解析器,在进行分析时我发现瓶颈在...文件读取!我摘录了非常简单的测试来比较的性能fstreams和FILE*读取数据的大斑点时:
#include <stdio.h>
#include <chrono>
#include <fstream>
#include <iostream>
#include <functional>
void measure(const std::string& test, std::function<void()> function)
{
auto start_time = std::chrono::high_resolution_clock::now();
function();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start_time);
std::cout<<test<<" "<<static_cast<double>(duration.count()) * 0.000001<<" ms"<<std::endl;
}
#define BUFFER_SIZE (1024 * 1024 * 1024)
int main(int argc, const char * argv[])
{
auto buffer = new char[BUFFER_SIZE];
memset(buffer, 123, BUFFER_SIZE);
measure("FILE* write", [buffer]()
{
FILE* file = fopen("test_file_write", "wb");
fwrite(buffer, 1, BUFFER_SIZE, file);
fclose(file);
});
measure("FILE* read", [buffer]() …Run Code Online (Sandbox Code Playgroud) 我用C++编写了很长时间.我总是想知道哪个执行速度更快printf或者cout?
情况:我正在用C++设计一个应用程序,我有一些约束,比如执行时间限制.我的应用程序在控制台上加载打印命令.那么哪一个更好printf或者cout?
我做了一些程序并看到了它scanf并且printf比使用cin和快得多cout?我的大多数程序在使用scanf/ printf超过限制时使用cin/ 时清除了在线编译器的执行时间限制,大多数是3秒或5秒cout.
std::istream(嗯,真的std::basic_istream)上的各种未格式化的输入函数,如read()、readsome()、getline()、ignore()都返回一个流。处理结果时,了解实际读取了多少个字符通常很重要。依赖字符串中的空字符显然不适用于二进制文件,或者ignore()甚至不涉及任何字符串,即strlen()完全不可能。
如何确定最后一次使用std::istream或更一般地使用 的无格式输入操作读取的字符数?std::basic_istream
c++ ×7
performance ×3
iostream ×2
benchmarking ×1
getline ×1
istream ×1
python ×1
stringstream ×1