독자적인 이진 데이터 파일 형식을 읽습니다. 형식은 기본적으로 헤더, 데이터, size_of_previous_data, header, data, size_of_previous_data, header, data, size_of_previous_data, ... 헤더의 일부는 다음 데이터 청크의 바이트 수와 그 직후에 나열된 크기 자료. 헤더는 256 바이트이고, 데이터는 일반적으로 ~ 2MB이고 size_of_previous_data는 32 비트 int입니다.큰 파일의 작은 분리 된 청크 읽기 (C++)
파일의 크기는 일반적으로 ~ GB이며, 원하는 데이터를 찾기 위해 수십 개의 파일을 수시로 검색해야합니다. 이렇게하기 위해서 내가 제일 먼저하는 일은 각 파일의 idex 즉, 헤더를 읽고 관련 데이터 (파일 및 바이트 번호)의 위치를 기록하는 것입니다. 내 코드는 기본적으로 fstream :: read()를 사용하여 헤더를 준비하고, 데이터 크기를 검사하고, fstream :: seekg()를 사용하여 데이터를 건너 뛴 다음 size_of_previous_data를 읽은 다음 파일의 끝에 도달 할 때까지 반복합니다.
제 문제는이 색인 생성이 너무 느리다는 것입니다. 데이터는 내 Windows 10 노트북의 내부 7200rpm 하드 드라이브에 있으며 작업 관리자는 내 하드 드라이브 사용량이 초과되었음을 보여 주지만 응답 속도가 일반적으로> 70ms 인 응답 속도가 약 1.5MB/s에 불과합니다. fstream :: get()을 사용하여 std :: fstream을 사용하여 파일을 읽고 있는데 헤더를 읽고 fstream :: seekg()를 사용하여 다음 헤더로 이동합니다.
나는 내 코드를 프로파일 링했으며 거의 전체 시간이 fstream :: read() 코드에서 size_of_previous_data 값을 읽는 데 소비된다. 나는이 작업을 수행 할 때 바로 다음 데이터가 버퍼링되어 다음 헤더를 가져 오는 fstream :: read()가 실제로 시간이 필요 없다고 추정합니다.
그래서 이것을 최적화하는 방법이 있는지 궁금합니다. 버퍼링 된 모든 읽기의 전체 버퍼가 거의 낭비 될 것입니다 (이 중 97 %가 8kB 버퍼 인 경우). 이 방법을 줄이는 방법이 있을까요? (아마도 기본 OS 버퍼도 변경할 수없는 방식으로 버퍼링 할 수 있습니다.)
처음에는 모든 파일을 읽지 않는 이유는 무엇입니까? GB 크기의 파일 검색 속도가 느리다는 것은 놀라운 일은 아니지만 보통 GBs의 RAM이 적당합니다. – user463035818
데이터의 크기가 이미 헤더에 저장되어있는 경우 데이터를 검색 할 때'size_of_previous_data '도 건너 뛰지 마십시오. ? 데이터 자체를 읽을 필요가있을 때까지 독서를 저장할 수 있으며이를 일종의 체크섬으로 사용할 수 있습니다. 그리고 한 번에 256 바이트 만 읽으면 그보다 더 큰 버퍼는 필요 없습니다. –
운영 체제에서 지원하는 경우 파일 매핑을 시도하십시오. 운영 체제는 청크 읽기를 메모리로 처리합니다. –