C ++尝试将每一帧的打印数据优化为二进制文件

C++ Attempt to optimize printing data to binary file for every frame

void demodlg::printData(short* data)
{
    FILE* pF;
    char buf[50];
    snprintf(buf, sizeof(buf), "%s\%s\%s%d.binary", "test", "data", "data", frameNum++);
    pF = fopen(buf, "wb");
    int lines = frameDescr->m_numLines;
    int samples = frameDescr->m_pLineTypeDescr[0].m_numSamples;
    int l, s;
    fprintf(pF, "\t");
    for (l = 0; l < lines; l++)
    {
        fprintf(pF, "%d\t", l);
    }
    fprintf(pF, "\n");
    for (s = 0; s < samples; s++)
    {
        fprintf(pF, "%d)\t", s);
        for (l = 0; l < lines; l++)
        {
            fprintf(pF, "%d\t", *(data + l * samples + s));
        }
        fprintf(pF, "\n");
    }
    fclose(pF);
}

我有上面的代码片段,它只接收一些数据,然后将其写出到一个二进制文件中。这个函数每秒被调用大约 20-30 次,所以我试图尽可能地优化它。它写入的每个文件大小约为 1 MB。理想情况下,我每秒可以写入 20-30 MB。截至目前,还没有达到这个速度。

有人对我如何进一步优化它有任何想法吗?

我最初是在更改为二进制文件之前写入 txt 文件,但令人惊讶的是,差异并不太明显。

此外,frameDescr 会针对每一帧进行更新,因此不幸的是,我认为我确实需要从内部访问行和样本变量。

我发现这个 post 是指 (Writing a binary file in C++ very fast),但我不确定如何将它应用到我的身上。

这是一个简短的示例,说明如何将数据数组写入二进制文件以及如何读回它。

我不理解您代码中 lines 的概念或目的,因此我没有尝试复制它。如果您确实有额外的数据需要写入以允许在读取时重建它,我已经放置了评论以注意您可以插入该代码的位置。

请记住,以二进制形式写入的数据必须以相同的方式读取,因此如果您以特定格式编写文本以从另一个程序使用它,那么二进制文件将无法为您工作,除非您修改其他程序或创建一个额外的步骤来读取二进制数据并在使用前写入文本格式。

假设以二进制形式写入数据有速度优势,那么添加一个额外的步骤将二进制数据转换为文本格式是有益的,因为当您不想保持特定帧速率时可以离线进行.

通常因为你标记了这个 c++ 我更喜欢在向量中操作数据并且可能使用 c++ 流来写入和读取数据,但我尽量保持它与你的代码尽可能相似。

#include <cstdio>
#include <stdint.h>

const size_t kNumEntries = 128 * 1024;

void writeData(const char *filename, int16_t *data, size_t numEntries)
{
    FILE *f = fopen(filename, "wb");
    if (!f)
    {
        fprintf(stderr, "Error opening file: '%s'\n", filename);
        return;
    }
    //If you have additional data that must be in the file write it here
    //either as individual items that are mirrored in the reader,
    //or using the pattern showm below for variable sized data.

    //Write the number of entries we have to write to the file so the reader 
    //will know how much memory to allocate how many to read.
    fwrite(&numEntries, sizeof(numEntries), 1, f);
    //Write the actual data
    fwrite(data, sizeof(*data), numEntries, f);

    fclose(f);
}

int16_t* readData(const char *filename)
{
    FILE *f = fopen(filename, "rb");
    if (!f)
    {
        fprintf(stderr, "Error opening file: '%s'\n", filename);
        return 0;
    }
    //If you have additional data to read, do it here. 
    //This code whould mirror the writing function.

    //Read the number of entries in the file.
    size_t numEntries;
    fread(&numEntries, sizeof(numEntries), 1, f);

    //Allocate memory for the entreis and read them into it.
    int16_t *data = new int16_t[sizeof(int16_t) * numEntries];
    fread(data, sizeof(*data), numEntries, f);

    fclose(f);

    return data;
}

int main()
{
    int16_t *dataToWrite = new int16_t[sizeof(int16_t) * kNumEntries];
    int16_t *dataRead = new int16_t[sizeof(int16_t) * kNumEntries];
    for (int i = 0; i < kNumEntries; ++i)
    {
        dataToWrite[i] = i;
        dataRead[i] = 0;
    }

    writeData("test.bin", dataToWrite, kNumEntries);
    dataRead = readData("test.bin");

    for (int i = 0; i < kNumEntries; ++i)
    {
        if (dataToWrite[i] != dataRead[i])
        {
            fprintf(stderr, 
                "Data mismatch at entry %d, : dataToWrite = %d, dataRead = %d\n",
                i, dataToWrite[i], dataRead[i]);
        }
    }
    delete[] dataRead;

    return 0;
}