0

我目前正在填写这样的课程(就我的目的而言,这相当慢):

void CBinLoader::LoadMatchesFromCompiledDat(clsMatches &uMatches)
{
int size = 0;
fread(&size,sizeof(int),1,m_infile);

for(int i = 0; i < size; i++)
{
    MatchNode newMatch;
    newMatch.EnteredCharacter = ReadWStringFromCompiledDat(m_infile);

    int PossibleResults_size = 0;
    fread(&PossibleResults_size,sizeof(int),1,m_infile);

    for(int j=0; j<PossibleResults_size; j++)
    {
        PossibleResult pr;

        fread(&pr.LenToUseFromEnteredString, sizeof(int), 1, m_infile);

        pr.Trans = ReadWStringFromCompiledDat(m_infile);
        pr.NextChars = ReadWStringFromCompiledDat(m_infile);
        pr.PrevTrans = ReadWStringFromCompiledDat(m_infile);
        pr.PrevPrevTrans = ReadWStringFromCompiledDat(m_infile);

        fread(&pr.SequenceID, sizeof(int), 1, m_infile);

        newMatch.PossibleResults.push_back(pr);
    }                   

    uMatches.Content().push_back(newMatch);

    }
}


wstring CBinLoader::ReadWStringFromCompiledDat(FILE *pFile)
{
    //read the length of the string
    int len = 0;
    fread(&len, sizeof(int), 1, m_infile);

    //make buffer with this length
    wchar_t* pBuffer = NULL;
    pBuffer = new wchar_t[len+1];
    memset(pBuffer, 0, (len+1)*sizeof(wchar_t));

    //read the string into the buffer
    fread(pBuffer, sizeof(wchar_t), len, m_infile);

    wstring result = pBuffer;

    delete pBuffer;
    return result;
}

是否可以一口气读完而不是一块一块地填满?

4

3 回答 3

2

可以将POD的内存映像写入文件,然后在 ( fread(pMyPod, sizeof(*pMyPod), 1, pFile);) 中将其读回。
但是,这是非常有限的:内存映像不是标准化的,因此在切换编译器版本时它甚至可能会发生变化,并且在切换平台时它很有可能会发生变化。
此外,更改类会使文件无用。

序列化(到磁盘)时,需要考虑很多事情。我不认为速度应该是主要问题。

于 2013-05-08T07:02:02.970 回答
0

您可以改进ReadWStringFromCompiledDat没有内存分配和内存初始化的方法:

wchar_t * pBuffer = NULL;
pBuffer = new wchar_t[len+1];
memset(pBuffer, 0, (len+1)*sizeof(wchar_t));
fread(pBuffer, sizeof(wchar_t), len, m_infile);

可以通过以下方式更改:

wchar_t pBuffer[len+1];
fread(pBuffer, sizeof(wchar_t), len, m_infile);
pBuffer[len] = 0;

使用这种新方法,您不会使用内存分配重载此方法。

于 2013-05-08T07:00:57.957 回答
0

理论上是的,但它需要一种完全不同的方式来构建数据,并且有可能使您的代码“依赖于平台”。

让我再给你一些“提示”:

  • 虽然我们不知道如何ReadWString...实现,但想想字符串是如何编写的:如果它们可能有可变长度,那么就没有办法“一劳永逸”,因为你必须知道字符串何时结束,然后再可以阅读以下一篇。

  • 如果您可以将所有要读取/写入的数据存储在静态定义的非多态数据结构中,例如

    struct { /* only plain types and statically sized arrays here */; };

您可以一次读取/写入整个支柱(无论有多大),但是如果您希望您的数据可以被不同类型的机器读取,您必须注意结构成员对齐(取决于编译器和平台)。

但在提供“随机优化”之前,请在启用所有优化的情况下编译代码后尝试分析您的代码。有多少“缓慢”是由于处理造成的,又有多少来自 IO 等待?

如果问题是 I/O,您可以在行缓冲区中读取整个文件,然后处理缓冲区中的数据。如果问题是处理,那么您必须重新考虑数据的表示方式和数据结构的存储方式。

于 2013-05-08T07:01:53.603 回答