C++快速写入文本文件

C++ write to text file fast

本文关键字:文本 文件 C++      更新时间:2023-10-16

我有大量值(整数)范围从 -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;
}

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

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<...>似乎是最快的方法(请参阅此图,其中绘制了使用不同方法的不同编译器所花费的时间:越短越好)。

似乎您的代码编写了一个大的数字序列,其中包含一些引入空格的奇怪规则:您确定不想在每个element之后放置一个空格,也许在每行之后放置一个换行符吗?

从您拥有的评论中获取:

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上调用它们。