C++文件读应该比露比还是C慢? 完全是C++的新的。

C++文件读应该比露比还是C慢? 完全是C++的新的。,c++,ifstream,C++,Ifstream,我比较C++、C和Ruby的各个方面,看看是否需要镜像库。目前,简单读取更新后的文件 编译VS 2017中的C++和C。C++是在RelaseX64模式下,或者至少编译然后运行 库或多或少地读取一个文件并将行拆分为三行,这三行构成一个对象的成员,然后存储在一个数组成员中 为了测试压力,我尝试了一个大文件380Mb7m线,现在更新后与C++和露比类似, 仅读取文件而不执行其他操作,性能如下所示: Ruby: 7s C#: 2.5s C++: 500+s (stopped running af

我比较C++、C和Ruby的各个方面,看看是否需要镜像库。目前,简单读取更新后的文件

编译VS 2017中的C++和C。C++是在RelaseX64模式下,或者至少编译然后运行

库或多或少地读取一个文件并将行拆分为三行,这三行构成一个对象的成员,然后存储在一个数组成员中

为了测试压力,我尝试了一个大文件380Mb7m线,现在更新后与C++和露比类似,

仅读取文件而不执行其他操作,性能如下所示:

Ruby: 7s
C#:   2.5s
C++:  500+s (stopped running after awhile, something's clearly wrong)
C++(release build x64): 7.5s
守则:

#Ruby
file = File.open "test_file.txt"
while !file.eof 
    line = file.readline
end

//C#
StreamReader file = new StreamReader("test_file.txt");
file.Open();
while((line = file.ReadLine()) != null){

}



//C++
#include "stdafx.h"
#include "string"
#include "iostream"
#include "ctime"
#include "fstream"
int main()
{
    std::ios::sync_with_stdio(false);
    std::ifstream file;
    file.open("c:/sandboxCPP/test_file.txt");
    std::string line;

    std::clock_t start;
    double duration;
    start = std::clock();
    while (std::getline(file, line)) {

    }
    duration = (std::clock() - start) / (double)CLOCKS_PER_SEC;
    std::cout << "\nDuration: " << duration;
    while (true) 
    {

    }
    return 0;
}
编辑:以下内容表现得非常好。0.03s

vector<string> lines;
string tempString = str.str();
boost::split(lines, tempString, boost::is_any_of("\n"));
start = clock();
cout << "\nCount: " << lines.size();
int count = lines.size();
string s;
for (int i = 0; i < count; i++) {
    s =  lines[i];
} 
s=我不知道boost在做什么的可能性。改变了表现

在循环结束时使用一组随机记录进行测试


谢谢

C++不会在你告诉它的时候自动写下所有的东西。相反,它会缓冲数据,以便一次写入所有数据,这通常会更快。要说“我真的想现在写这个”,你需要说一些类似于STD::CUT< P>的评论和最初发布的代码,它现在已经被修复[现在删除],以前有一个编码错误,I++失踪,阻止了C++程序输出任何东西。这加上完整代码样本中的whiletrue循环将呈现与问题中所述症状一致的症状,即用户等待500秒,看不到输出,强制终止程序。这是因为它将在不输出任何内容的情况下完成文件读取,并进入故意添加的无限循环

对于120万个文件,修订后的完整源代码根据~1.6s中的注释正确完成。我对提高绩效的建议如下:

确保您是在发布模式而不是调试模式下编译。鉴于用户指定他们使用的是Visual Studio 2017,我建议查看Microsoft官方文档以获得详细的解释

为了更容易诊断问题,不要在程序末尾添加无限循环。而是从powershell/cmd运行可执行文件,并确认其正确终止

编辑:我还要补充:

要获得准确的计时,还需要考虑操作系统磁盘缓存。多次运行每个基准测试以“预热”磁盘缓存。
你能发布你的完整源代码吗。您提供的C++代码不应该编译它缺少一个关闭括号。请参阅这可能是一个复制:STD::IOS::SycCyWuStdioFalsSE;不管减速的原因是什么,分析一个非发布版本是没有意义的。您实际上是在要求编译器在调试模式下生成更易于调试的输出,而不是快速输出,那么为什么要对其进行测量呢?请也在发布模式下尝试,并报告速度的差异。@CBusBus如果我们有完整的文件,这会有所帮助。保存一个新文件,删除所有注释掉的代码,然后尝试编译并运行该文件。它应该包含include、int main等内容,“\n”不会导致刷新吗?它不会无限地缓冲afaict。@JarraMcIntyre,我认为这会刷新操作系统缓冲区;我更熟悉POSIX这样的低级细节,但iostreams有自己的内部缓冲区。我只是再次确认,不是在Windows上std::cout Oops,我对一些缓冲发生在哪里感到困惑,这就是为什么我对sync_和stdio的效果感到惊讶。如果您正在同步,那么您肯定会被行缓冲,因为底层C流正在同步,并且\n会导致刷新。如果您关闭与_stdio的sync_,那么我认为iostreams根本没有行缓冲的概念。根据cpp参考,cout确实提供了一些关于何时在std::系统调用之前刷新std::flush、std::endl的保证,但是“\n”刷新是否是实现定义的。我相信您的测试表明,如果启用了sync_with_stdio,它确实会刷新MS stl实现。这是有道理的,因为IIRC、stdout确实在'\n'上刷新。如果您禁用了同步,那么std::cout可以使用它自己的缓冲实现,它不一定具有相同的行为。谢谢您的建议。最后,我使用了boost::split和一个循环,对于1.24M行,它减少到了0.03s。我接受了这个答案,因为调试编译模式是一个重要的问题。没有问题。很高兴事情解决了。谢谢你的接受。