C ++快速写入文本文件

时间:2014-11-27 23:58:33

标签: c++ ofstream

我有大量的大矩阵,其值(整数)范围从-1到15,我想用下面的函数写入文本文件。写入速度似乎约为0.1 MB / s,所以我玩了一下,看看我是否可以让它更快,没有任何结果。如何让它更快?

bool mymap::write_one_mat(string txtfile, matrix& mat)
{
ofstream myfile (txtfile, ios::app|ios::binary);

int element;

if (myfile.is_open())
{
    int rows = mat.get_rows();
    int cols = mat.get_cols();
    myfile << "<";
    for(int i = 1; i <= rows; ++i)
    {
        for(int j = 1; j <= cols; ++j)
        {
            element = mat.get_element(i,j);
            if(element < 0 || element > 9)
            {
                myfile << to_string(element);
            }
            else
            {
                myfile << " ";
                myfile << to_string(element);
            }
        }
    }

    myfile << ">\n";

    myfile.close();
    return true;
}
else
    return false;
}

2 个答案:

答案 0 :(得分:1)

正如已经评论的那样,您可能希望开始删除对std::to_string()的不必要使用:流可以直接愉快地格式化整数。但是,即使直接格式化整数,在大多数实现中似乎都会使用dynamic_cast<...>(..)来进行关于facet的一些不必要的开销。因此,使用以下方法手动格式化整数可能会更快:

std::locale loc(std::locale(), new std::num_put<char, char*>());
std::num_put<char, char*> const& np(std::use_fast<std::num_put<char, char*>>(loc));
char buffer[1024];
char* next(buffer);
for (int i(1); i <= rows; ++i) {
     for (int j(1); j <= cols; ++j) {
         int element(mat.get_element(i, j));
         if (element < 0 || element < 9) {
             *next++ = ' ';
         }
         next = np.put(next, myfile, ' ', element);
         if (std::numeric_limits<int>::digits10 + 1 <= (buffer + 1014) - next)) {
             myfile.write(buffer, next - buffer);
             next = buffer;
         }
     }
}
myfile.sputn(buffer, next - buffer);

直接使用std::num_put<...>似乎是最快的方法(请参阅this graph,其中显示了使用不同方法的不同编译器所花费的时间:越短越好)。

似乎你的代码写了一大串数字,并带有一些引入空格的奇怪规则:你确定你不想在每个element之后放一个空格,也许每行之后换一个换行符?

答案 1 :(得分:0)

从您的评论中获取:

bool mymap::write_one_mat(std::string const& txtfile, matrix const& mat)
{
    std::ios_base::sync_with_stdio(false);
    std::ofstream myfile(txtfile, std::ios_base::app | std::ios_base::binary);

    if (myfile.is_open())
    {
        int rows = mat.get_rows();
        int cols = mat.get_cols();

        myfile << "<";
        for (int i = 1; i <= rows; ++i)
        {
            for (int j = 1; j <= cols; ++j)
            {
                int element = mat.get_element(i, j);
                if (!(element < 0 || element > 9))
                    myfile << " ";
                myfile << element;
            }
        }
        myfile << ">\n";
    }
    return static_cast<bool>(myfile);
}

此外,txtfilemat的类型已更改为对const的引用。这是有道理的,因为您的write_one_mat方法不会修改其参数。确保mat::get_rows()mat::get_cols()get_element()const方法,以便mat可以调用它们。