将巨大的2D矢量写入文本文件太慢,如何提高性能?

时间:2015-08-15 06:44:10

标签: c++ vector ofstream

我有10个大的(3400万个单元格)2D网格向量存储双精度数。写入时,它们的尺寸超过200 mb。我使用ofstream对象将它们写入文本文件(csv格式),一次一个元素,使用两个for循环(一个用于我的行,一个用于我的列)。他们采取长期写作的方式。是否有更快的方式从这些向量写入?

这是我的代码:

// Resizing of vectors
flowDirGrid.resize(rows, std::vector<double>(cols, NODATA));

// Do some processing
....

// Outputting processed data
ofstream outfile3("FlowDir.dat");
if(!outfile3.good())
    return;

for(int i=0; i<rows; i++)        
    {
        for (int j=0; j<cols; j++)
        {
            if(elevation[i][j]!=NODATA)
                outfile3 << flowDirGrid[i][j]<<" ";
            else
                outfile3 << NODATA<<" ";
        }
        outfile3 << std::endl;
    }

outfile3.close(); 

我正在使用C ++和Visual Studio 2012.

修改即可。我删除了所有std :: endl实例并替换为“\ n”,并且仍需要17分钟来编写每个输出文件。我可能会转向使用推荐的C方法。

使用三元而不是if-else梯子会加速吗?

3 个答案:

答案 0 :(得分:2)

C ++ iostream库很方便,但速度很慢。 fprintf会更好地为您服务。另外,使用&#39; \ n&#39;而不是endl,因为后者强制流冲洗。

#include <cstdio>
#include <chrono>
#include <fstream>
#include <iostream>
#include <random>
#include <vector>

using namespace std;
using namespace std::chrono;

void PrintC(const double * data, size_t n, const char * path)
{
    FILE * f = fopen(path, "w");
    for (size_t i(0); i != n; ++i)
        fprintf(f, "%lf ", data[i]);
    fclose(f);
}

void PrintCpp(const double * data, size_t n, const char * path)
{
    ofstream f(path);
    for (size_t i(0); i != n; ++i)
        f << data[i] << ' ';
}

template<typename PrintT>
void Time(const vector<double> & data, PrintT Print, const char * path, const char * text)
{
    auto s = steady_clock::now();
    Print(data.data(), data.size(), path);
    auto f = steady_clock::now();

    cout << text << ": " << duration_cast<duration<double>>(f - s).count() << endl;
}

int main()
{
    vector<double> data(34000000);
    default_random_engine generator;
    uniform_real_distribution<double> distribution(0.0, 1.0);
    for (size_t i(0); i != data.size(); ++i)
        data[i] = distribution(generator);

    Time(data, PrintC,   "test1.dat", "c");
    Time(data, PrintCpp, "test2.dat", "c++");
}

Visual Studio 2013 Professional,发布配置:

  c:17.2682
  c ++:32.0839

答案 1 :(得分:1)

200 MB的20分钟似乎真的长。您遇到性能问题,因此必须按顺序测试元素。

  1. 取一个200 mb并复制它(直接在os级别)。如果需要大约10分钟,瓶颈在这里:购买更快的磁盘

  2. 制作一个测试程序,生成随机值集(不是全部为0.因为0.转换比其他双值更简单,所以只是*不同的值),写下时间(至少包括第二个)使用上面的代码来编写文件并再次写入时间 - 或者,您可以使用当前代码只添加两次。运行几次。如果它比第一次测试花费的时间要长得多,请在此报告第一次测试和第二次测试的时间。

  3. 如果上述测试均未花费大约10分钟,则问题出现在其余代码中......

答案 2 :(得分:0)

根据this answer std::endl导致刷新流。请尝试使用\n