Cpp快速读取双倍文件的双倍文件

时间:2014-12-29 07:05:57

标签: c++ performance file-io binary double

从C或C ++,我想尽快读取二进制格式的双精度文件。

文件很小,通常大约100KB(顶部200 KB)。我希望能够:

  • 阅读双打文件。
  • 将它们转换/存储在双打矢量
  • 遍历向量。

在2毫秒内完成这些操作。如果可能,在这个系统上。目前它在4-6毫秒左右。

帮助但没有解决问题的主题:

Link 1

Link 2 - >这甚至没有编译。

Link 3 - >这对双打不起作用。

Link 4 - >这样做。

以下是我的文件解析器:

" C"阅读方式:

void OfflineAnalyser::readNParseData(const char* filePath, vector<double> *&data){

    // Temporary Variables
    FILE* pFile;
    long fileSize;
    double *fileBuffer;
    size_t sizeOfBuffer;
    size_t result;

    // Open File
    pFile = fopen(filePath, "rb");

    if (pFile == NULL){
        cout << "File: " << filePath << " does not exist" << endl;
    }

    // Check whether the parameter is already full
    if (!data){
        // Reset the output
        data->clear();
        data = 0;
    }

    // Obtain file size:
    fseek(pFile, 0, SEEK_END);
    fileSize = ftell(pFile);
    rewind(pFile);

    // allocate memory to contain the whole file:
    fileBuffer = (double*)malloc(fileSize);

    if (fileBuffer == NULL) { fputs("Memory error", stderr); exit(2); }

    // copy the file into the buffer:
    result = fread(fileBuffer, 1, fileSize, pFile);
    if (result != fileSize) {
        fputs("Reading error", stderr); 
        system("pause");
        exit(3);
    }

    // the whole file is now loaded in the memory buffer.
    sizeOfBuffer = result / sizeof(double);

    // Now convert the double array into vector
    data = new vector<double>(fileBuffer, fileBuffer + sizeOfBuffer);

    free(fileBuffer);
    // terminate
    fclose(pFile);
}

方法2:C ++风格

void OfflineAnalyser::readNParseData2(const char* filePath, vector<double> *&data){

    ifstream ifs(filePath, ios::in | ios::binary);

    // If this is a valid file
    if (ifs) {
        // Temporary Variables
        std::streampos fileSize;
        double *fileBuffer;
        size_t sizeOfBuffer;

        // Check whether the parameter is already full
        if (!data){
            // Reset the output
            data->clear();
            data = 0;
        }

        // Get the size of the file
        ifs.seekg(0, std::ios::end);
        fileSize = ifs.tellg();
        ifs.seekg(0, std::ios::beg);

        sizeOfBuffer = fileSize / sizeof(double);
        fileBuffer = new double[sizeOfBuffer];

        ifs.read(reinterpret_cast<char*>(fileBuffer), fileSize);

        // Now convert the double array into vector
        data = new vector<double>(fileBuffer, fileBuffer + sizeOfBuffer);

        free(fileBuffer);
    }
}

对此代码的任何建议表示赞赏。随意输入您自己的代码。 如果我能看到一个用于双打或istream_iterator解决方案的std :: copy,我会很高兴。

提前致谢。

1 个答案:

答案 0 :(得分:-1)

由于vector按顺序存储元素,因此将文件缓冲区读取到向量的数据缓冲区会更有效。

void readNParseData(const char* filePath, vector<double>& data){

    // Temporary Variables
    FILE* pFile;
    long fileSize;
    size_t result;

    // Open File
    pFile = fopen(filePath, "rb");

    if (pFile == NULL){
        cout << "File: " << filePath << " does not exist" << endl;
    }

    // Check whether the parameter is already full
    if (!data.empty()){
        data.clear();
    }

    // Obtain file size:
    fseek(pFile, 0, SEEK_END);
    fileSize = ftell(pFile);
    rewind(pFile);

    data.resize(fileSize / 8);
    if(fread(&(data[0]), 1, fileSize, pFile) != fileSize)
    {
        cout << "read error" << endl;
    }

    fclose(pFile);
}

我已经测试了您的代码和我的解决方案。当文件大小为20,000KB时,您的代码大约需要21ms,而我的解决方案大约需要16ms。

此外,您的代码中存在错误。 if(!data) shouble be if(data)