C ++文件读取应该比Ruby还是C#慢?

时间:2018-01-05 21:13:58

标签: c++ ifstream

完全是C ++的新手。

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

在VS 2017中编译C ++和C#。C ++处于发布(x64)模式(或至少编译然后运行)

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

对于压力测试,我尝试了一个大型文件380MB(7M行)(更新后)现在获得与C ++和Ruby类似的性能,

纯粹阅读文件而不执行任何其他操作,性能如下:

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 =关于我不知道提升正在做什么的可能性。改变了表现。

在循环结束时使用随机记录的cout进行测试。

由于

2 个答案:

答案 0 :(得分:2)

根据评论和最初发布的代码(现已修复[现已删除]),之前出现了编码错误(i++缺失),导致C ++程序无法输出任何内容。这加上完整代码示例中的while(true)循环将呈现与问题中所述的一致的症状(即,用户等待500s看不到输出并且强制终止程序)。这是因为它将完成读取文件而不输出任何内容并进入故意添加的无限循环。

修改后的完整源代码正确地完成(根据评论)~1.6s内的120万个文件。我对提高绩效的建议如下:

  1. 确保您在发布模式下编译(不是调试模式)。鉴于用户已指定他们使用Visual Studio 2017,我建议您查看官方Microsoft文档(https://msdn.microsoft.com/en-us/library/wx0123s5.aspx)以获得详尽说明。

  2. 为了更容易诊断问题,请不要在程序结束时添加无限循环。而是从powershell /(cmd)运行可执行文件并确认它正确终止。

  3. 编辑:我还想补充一下:

    1. 为了准确计时,您还需要考虑操作系统磁盘缓存。多次运行每个基准测试以进行预热&#39;磁盘缓存。

答案 1 :(得分:0)

C ++不会在您告诉它的瞬间自动写入所有内容。相反,它缓冲数据,以便它可以一次写入所有数据,这通常更快。要说“我现在真的想写这个。”,你需要说std::cout << std::flush之类的内容(如果你使用std::endl来结束你的行,它会自动执行此操作)。

通常你不需要这样做;程序退出时,或者当您要求用户输入时,或者类似的事情,都会刷新缓冲区。但是,您的程序不会退出,因此它永远不会刷新其缓冲区。你读取输入,然后程序永远执行while(true),永远不会给出输出。

解决方案很简单:在程序结束时删除while循环。你不应该那样;人们通常认为控制台程序在完成时退出。我会猜到你有这个,因为Visual Studio会在程序结束时自动关闭控制台窗口,但显然它不能用 Ctrl + F5 执行此操作,你使用,所以我不确定。