2016-08-06 1 views
-4

나는 파일에서 std::wstring으로 매우 큰 XML 파일을로드해야하는 C++ 프로젝트 (VS2008 사용)에서 작업하고 있습니다.std :: string의 크기를 조정하는 가장 빠른 방법은 무엇입니까?

//std::wstring str; 
//size_t ncbDataSz = file size in bytes 

str.resize(ncbDataSz/sizeof(WCHAR)); 

하지만 내 현재의 문제는 resize 방법은 x64에, (난 그냥 데이터 3GB의 그것을 테스트 큰 문자열 크기에 다소 시간이 오래 걸리는 것입니다 : 현재 데이터 전에 다음 줄 매장량 메모리로드 프로젝트, 데스크톱 PC에서 무료 RAM이 12GB이고 완료하는 데 약 4-5 초가 걸렸습니다.)

궁금합니다. std::string 크기를 조정하는 더 빠른 (최적화 된) 방법이 있습니까? 나는 Windows 만 요구하고있다.

+3

'std :: string :: reserve' 예비역,'std :: string :: resize' 또한 메모리에 쓴다. IM을 덮어 씁니다. mediate, 나는 생각한다. – LogicStuff

+0

크기를 조정 하시겠습니까? – user463035818

+0

@LogicStuff :'예약 '은 이상한 짐승입니다. 메모리를 "예약"하지만 연속 바이트 배열로 직접 액세스 할 수는 없습니다. 맞습니까? 그 위에'append'라고 부를 필요가 있습니다. 이 경우이 유형 최적화에 대해서는 나에게 쓸모가 없다. – c00000fd

답변

1

입력 문자열의 크기를 조정하는 대신 크기 조정이 모든 요소를 ​​초기화하기 때문에 std::string::reserve을 사용하여 할당 할 수 있습니다.

당신은 당신을 위해 성능 개선되는지 확인하기 위해이 같은 일을 시도 할 수 :

std::wstring load_file(std::string const& filename) 
{ 
    std::wifstream ifs(filename, std::ios::ate); 

    // errno works on POSIX systems not sure about windows 
    if(!ifs) 
     throw std::runtime_error(std::strerror(errno)); 

    std::wstring s; 
    s.reserve(ifs.tellg()); // allocate but don't initialize 
    ifs.seekg(0); 

    wchar_t buf[4096]; 
    while(ifs.read(buf, sizeof(buf)/sizeof(buf[0]))) 
     s.append(buf, buf + ifs.gcount()); // this will never reallocate 

    return s; 
} 
+0

감사. 하지만 당신이하는 일은 두 개의 버퍼를 미리 할당하는 것입니다 :'s.reserve'와'wchar_t buf' 그리고 나는 단지 하나만 가지고 도망 치려고합니다. 그래서's.reserve'를 수행 한 후에 어떻게 직접로드 할 수 있습니까? 또는'ReadFile (hFile, & s [0], sz, szRead, NULL);'크기를 조정해야합니다. 그러나 어떻게? – c00000fd

+0

@ c00000fd 예약 된 메모리를 읽을 수 없습니다. 그러나 'buf [4096]'에 대한 할당은 빠르게 번개가가는 스택에있다 (하나의 명령?). 하루가 끝나면 측정이 더 빠를 지 여부 만 알려줍니다. – Galik

+0

저는 GB의 데이터에 대해 이야기하고 있습니다. 따라서 스택은 문제가되지 않습니다. 그리고 파일에서 작은 덩어리로 그것을로드하면'resize'를 사용하지 않은 것보다 훨씬 느려집니다. – c00000fd

1

당신은 할당에 아무것도 안하는 char_traits와 basic_string 인스턴스화 할 수 있습니다 (계산) :

#include <string> 

struct noinit_char_traits : std::char_traits<char> { 
    using std::char_traits<char>::assign; 
    static char_type* assign(char_type* p, std::size_t count, char_type a) { return p; } 
}; 

using noinit_string = std::basic_string<char, noinit_char_traits>; 

주를이 그것은 또한 basic_string :: fill() 등의 함수에 영향을 미친다.

관련 문제