2013-11-05 39 views
2

我读在阵列的寄存器的夹头中的一个文件的大小为4096附加数据块到另一个数组迅速

我有循环之外的容器阵列,我想“追加”的大量的数据按顺序排列,最快和最有效的方法是什么?

PointRecord4 * AllRegisters = new PointRecord4[ptr->Number_of_Point_records]; 

    if (ptr->Point_Data_Format_ID == 4) 
     switch ((*ptr).Point_Data_Format_ID) 
     { 
     case 4: 
      { 
       PointRecord4 registers[4096]; 
       ULONG32 pointsToRead = 4096; 
       ULONG32 pointsLoaded = 0;    
       ULONG32 i; 

       for (i = 0; pointsLoaded < ptr->Number_of_Point_records; i += pointsToRead) 
       { 
        pointsToRead = std::min(pointsToRead, ptr->Number_of_Point_records - pointsLoaded); 
        input_file.read(PTR(&registers), sizeof(PointRecord4) * pointsToRead); 
        pointsLoaded += pointsToRead; 

        //Insert registers[4096] into AllRegisters, Appending it 
       } 
      } break; 
    } 

我试图简单地迭代4096,并推回到载体,但这是令人难以置信的缓慢。下面

是我的全部代码:

#include "vgl.h" 
#include <fstream> 
#include <iostream> 
#include <vector> 
#include <string.h> 


using namespace std; 

#define PTR reinterpret_cast<char *> 

#pragma pack(1) 
typedef struct LasHeader 
{ 
    char   File_Signature[4];       // 4 Bytes 
    UINT16 FileSourceID;           // 2 Bytes 
    UINT16 Global_Encoding;          // 2 Bytes 
    ULONG32 GUID1;            // 4 Bytes 
    UINT16 GUID2;            // 2 Bytes 
    UINT16 GUID3;            // 2 Bytes 
    UCHAR GUID4[8];            // 2 Bytes 
    UCHAR Version_Major;          // 1 Bytes 
    UCHAR Version_Minor;          // 1 Bytes 
    CHAR   System_Identifier[32];      // 32 Bytes 
    CHAR   Generating_Software[32];      // 32 Bytes 
    UINT16 File_Creation_Day_Of_Year;       // 2 Bytes 
    UINT16 File_Creation_Year;         // 2 Bytes 
    UINT16 Header_Size;           // 2 Bytes 
    ULONG32 Offset_to_point_data;        // 4 Bytes 
    ULONG32 Number_of_Variable_Length_Records;     // 4 Bytes 
    CHAR Point_Data_Format_ID;         // 1 Bytes 
    UINT16 Point_Data_Record_Length;        // 2 Bytes 
    ULONG32 Number_of_Point_records;        // 4 Bytes 
    ULONG32 Number_of_points_by_return[5];      // 20 Bytes/Verified 

    double X_Scale_Factor;          // 8 bytes/Verified 
    double Y_Scale_Factor;          // 8 bytes 
    double Z_Scale_Factor;          // 8 bytes 
    double X_Offset;            // 8 bytes 
    double Y_Offset;            // 8 bytes 
    double Z_Offset;            // 8 bytes 
    double Max_X;            // 8 bytes 
    double Min_X;            // 8 bytes 
    double Max_Y;            // 8 bytes 
    double Min_Y;            // 8 bytes 
    double Max_Z;            // 8 bytes 
    double Min_Z;            // 8 bytes 

    #ifdef FULLWAVE 
     unsigned long long Start_of_Waveform_Data_Packet_Record; // 8 bytes 
    #endif 

    union 
    { 
     char* MemoryBlock; 
    }; 

} *header; 

struct PointRecord4 
{ 
    UINT32 X; 
    UINT32 Y; 
    UINT32 Z; 
    UINT16 Intensity; 
    CHAR BitMask; 
    CHAR Classification; 
    CHAR ScanAngleRank; 
    CHAR UserData; 
    UINT16 PointSourceID; 
    double GPSTime; 
    CHAR WPDI; 
    UINT64 WFOffset; 
    UINT32 WFPacketSize; 
    float WFReturnLocation; 
    float WFXt; 
    float WFYt; 
    float WFZt; 
}; 

extern header ptr = new LasHeader; 

HRESULT OpenLasFile(char *path) 
{ 
    HRESULT result; 
    ifstream input_file(path, ios::in | ios::binary); 
    result = GetLastError(); 

    input_file.read(PTR(ptr), sizeof(LasHeader)); 
    result = GetLastError(); 
    input_file.seekg (ptr->Offset_to_point_data, input_file.beg); 

    PointRecord4 * AllRegisters = new PointRecord4[ptr->Number_of_Point_records]; 

    if (ptr->Point_Data_Format_ID == 4) 
     switch ((*ptr).Point_Data_Format_ID) 
     { 
     case 4: 
      { 
       PointRecord4 registers[4096]; 
       ULONG32 pointsToRead = 4096; 
       ULONG32 pointsLoaded = 0;    
       ULONG32 i; 

       for (i = 0; pointsLoaded < ptr->Number_of_Point_records; i += pointsToRead) 
       { 
        pointsToRead = std::min(pointsToRead, ptr->Number_of_Point_records - pointsLoaded); 
        input_file.read(PTR(&registers), sizeof(PointRecord4) * pointsToRead); 
        pointsLoaded += pointsToRead; 

        //Insert registers[4096] into AllRegisters, Appending it 
       } 
      } break; 
    } 

    input_file.close(); 

    return result; 
} 

回答

0

对于你特定的情况下,你可以只读取到该目标缓冲器保存副本:

input_file.read(AllRegisters + pointsLoaded, sizeof(PointRecord4) * pointsToRead); 

在其他情况下,复制是必要的, memcpy是复制大量POD数据的最佳选择。

0

目前还不清楚为什么你不直接阅读AllRegisters

但是,我怀疑追加阶段是而不是的瓶颈。当你像这样以大块读取数据时,使用无缓冲的I/O是值得的。磁盘I/O将成为您的限制因素,而不是内存I/O。

查看我的帖子关于buffered vs unbuffered I/O in C

这是一个邮政处理unbuffered I/O on std::ifstream

相关问题