【问题标题】:Cpp Read Small Binary File of doubles FastCpp 快速读取双打的小二进制文件
【发布时间】:2014-12-29 07:05:56
【问题描述】:

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

文件很小,通常约为 100 KB(最多 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);
}

方法二: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 ,我会很高兴。

提前致谢。

【问题讨论】:

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


    【解决方案1】:

    由于vector是按顺序存储元素的,所以将文件缓冲区读入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 时,你的代码大约需要 21 毫秒,而我的解决方案大约需要 16 毫秒。

    此外,您的代码中存在错误。 if(!data)应该是if(data)

    【讨论】:

    • 没有错误。我上面给出的代码工作得很好(如果数据为空(0),!数据将为1,它将进入if)。事实上,我已经用指针尝试过你的代码,必须修复以下两行导致 esception 的问题: if (!data->empty()){ ] 给出 exp 和 data->resize(fileSize / 8);也给出了例外。修复了它们,但 fread 也会产生异常。所以我尝试了你的代码版本(正是你上面给出的代码)。读取的双精度值不正确。我正在检查十六进制编辑器和我自己的代码。返回的值不正确。也许你可以修改你的代码?
    • 抱歉,我在调用函数之前通过“vector *data = 0”更正了对函数的调用,现在我正在执行 if(data != 0) 检查.感谢您指出这一点。
    猜你喜欢
    • 2018-03-23
    • 1970-01-01
    • 2012-12-25
    • 2012-05-01
    • 2021-10-18
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2016-02-22
    相关资源
    最近更新 更多