Я думаю, что STL заставляет мое приложение утроить использование памяти - PullRequest
2 голосов
/ 10 декабря 2008

Я ввожу файл 200 МБ в свое приложение, и по очень странной причине использование памяти моим приложением составляет более 600 МБ. Я пробовал vector и deque, а также std :: string и char * безрезультатно. Мне нужно, чтобы использование памяти моим приложением было почти таким же, как у файла, который я читаю, любые предложения были бы чрезвычайно полезны. Есть ли ошибка, которая вызывает такое большое потребление памяти? Не могли бы вы точно определить проблему или мне все это переписать?

Windows Vista SP1 x64, Microsoft Visual Studio 2008 SP1, 32-разрядная версия, процессор Intel

Целое приложение до сих пор:

#include <string>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <iterator>
#include <algorithm>
#include <time.h>



static unsigned int getFileSize (const char *filename)
{
    std::ifstream fs;
    fs.open (filename, std::ios::binary);
    fs.seekg(0, std::ios::beg);
    const std::ios::pos_type start_pos = fs.tellg();
    fs.seekg(0, std::ios::end);
    const std::ios::pos_type end_pos = fs.tellg();
    const unsigned int ret_filesize (static_cast<unsigned int>(end_pos - start_pos));
    fs.close();
    return ret_filesize;
}
void str2Vec (std::string &str, std::vector<std::string> &vec)
{
    int newlineLastIndex(0);
    for (int loopVar01 = str.size(); loopVar01 > 0; loopVar01--)
    {
        if (str[loopVar01]=='\n')
        {
            newlineLastIndex = loopVar01;
            break;
        }
    }
    int remainder(str.size()-newlineLastIndex);

    std::vector<int> indexVec;
    indexVec.push_back(0);
    for (unsigned int lpVar02 = 0; lpVar02 < (str.size()-remainder); lpVar02++)
    {
        if (str[lpVar02] == '\n')
        {
            indexVec.push_back(lpVar02);
        }
    }
    int memSize(0);
    for (int lpVar03 = 0; lpVar03 < (indexVec.size()-1); lpVar03++)
    {
        memSize = indexVec[(lpVar03+1)] - indexVec[lpVar03];
        std::string tempStr (memSize,'0');
        memcpy(&tempStr[0],&str[indexVec[lpVar03]],memSize);
        vec.push_back(tempStr);
    }
}
void readFile(const std::string &fileName, std::vector<std::string> &vec)
{
    static unsigned int fileSize = getFileSize(fileName.c_str());
    static std::ifstream fileStream;
    fileStream.open (fileName.c_str(),std::ios::binary);
    fileStream.clear();
    fileStream.seekg (0, std::ios::beg);
    const int chunks(1000); 
    int singleChunk(fileSize/chunks);
    int remainder = fileSize - (singleChunk * chunks);
    std::string fileStr (singleChunk, '0');
    int fileIndex(0);
    for (int lpVar01 = 0; lpVar01 < chunks; lpVar01++)
    {
        fileStream.read(&fileStr[0], singleChunk);
        str2Vec(fileStr, vec);
    }
    std::string remainderStr(remainder, '0');
    fileStream.read(&remainderStr[0], remainder);
    str2Vec(fileStr, vec);      
}
int main (int argc, char *argv[])
{   
        std::vector<std::string> vec;
        std::string inFile(argv[1]);
        readFile(inFile, vec);
}

Ответы [ 14 ]

0 голосов
/ 11 декабря 2008

Может быть, вам стоит уточнить, почему вам нужно прочитать весь файл в памяти, я подозреваю, что, вероятно, есть способ сделать то, что вы хотите, не считывая весь файл в память сразу. Если вам действительно нужна эта функциональность, загляните в отображенные в память файлы, которые, вероятно, будут более эффективными, чем вы пишете эквивалент. Ваша внутренняя структура данных может затем использовать смещение в файл. Кстати, убедитесь, что вам нужно обрабатывать кодировку символов.

0 голосов
/ 10 декабря 2008

Увеличение векторов с помощью pushBack () приведет к фрагментации памяти и неэффективному использованию памяти. Вместо этого я бы попытался использовать списки и создавать вектор (если он вам нужен) только тогда, когда вы точно знаете, сколько элементов ему потребуется.

0 голосов
/ 10 декабря 2008

Я не знаю, относится ли это к делу, потому что я не знаю, как выглядит ваш файл.

Но вы должны знать, что при хранении очень короткой строки std :: string может иметь значительные накладные расходы. И если вы индивидуально начинаете использовать char * для очень коротких строк, вы также увидите все накладные расходы блока выделения.

Сколько строк вы помещаете в этот вектор, и какова их средняя длина?

0 голосов
/ 10 декабря 2008

Попробуйте использовать список вместо вектора. Векторы (почти всегда) линейны в памяти.

Конечно, тот факт, что у вас есть строки, которые (почти всегда) копируются при изменении, подсчитываются по ссылкам, должен сделать это меньшей проблемой, но это может помочь.

...