2017-12-30 8 views
5

은 다음 내 경우처럼 : C++ 표준 : 이제 stringstream 운영 최적화

  1. 내가 (숯불 *)
  2. 내 목표는 같은 바이너리 나는 표준 : : fstream과에서 읽고 있어요 파일을 읽을 수술을 파일, 진수 형식에서 모든 바이트를 가지고, 다음 변수 문자열에 추가하기
  3. 의 말을하자, 예를 들어 2

항목에 따라 형식 파일의 전체 내용을 유지해야하는 문자열 변수 나는 다음 빈을 가지고있다. 예상대로 접근 위

stringstream fin;; 

for (size_t i = 0; i < fileb_size; ++i) 
{ 
fin << hex << setfill('0') << setw(2) << static_cast<uint16_t>(fileb[i]); 
} 

// this would yield the output "D0469857A0249956A3" 

return fin.str(); 

은, 그러나,이 작품 : 진 파일 내용을 다음과 같이

D0 46 98 57 A0 24 99 56 A3

나는 각 바이트를 포맷하고있어 방법은 내가 이해하는 대용량 파일은 매우 느리다. stringstream은 입력 포맷을위한 것입니다!

제 질문은 그러한 코드를 최적화하는 방법이나 함께 사용하는 방법이 있습니까? 필자의 유일한 제약은 출력이 위와 같이 문자열 형식이어야한다는 것입니다.

감사합니다.

+3

iostream은 효율성을 높이기 위해 설계되지 않았습니다. 특정 사용 사례의 경우 구현 고유 파일 I/O를 능가 할 수 없습니다. 아니면, 더 나쁜 경우에는 C의'FILE *'을 가져 와서 직접 최적화 된 16 진수 변환 코드를 굴려 라. 효율성을 위해 이길 수는 없었습니다. 로켓 과학이 아닙니다. 적어도 C와 C++를 배웠던 날에 이것은 전형적인 숙제 과제였습니다 : 16 진법을 읽고 그것을 변환하십시오. –

+1

"매우 느립니다"무엇에 비해? –

+1

출력 문자열에 대해 [예약 크기] (https://stackoverflow.com/q/1941064/995714)를 시도 했습니까? 출력의 크기를 계산하기 쉽고 배열을 여러 번 재 할당하는 것을 피하기 위해 입력 크기를 이미 알고 있습니다. –

답변

4

std::stringstream은 다소 느립니다. 그것은 사전 할당되지 않으며 항상 적어도 한 번 검색하여 문자열을 복사해야합니다. 또한 16 진수로의 변환은 손으로 더 빠르게 코딩 될 수 있습니다.

는이 같은 일이 더 성능이 좋은 것 같아요 :

// Quick and dirty 
char to_hex(unsigned char nibble) 
{ 
    assert(nibble < 16); 

    if(nibble < 10) 
     return char('0' + nibble); 

    return char('A' + nibble - 10); 
} 

std::string to_hex(std::string const& filename) 
{ 
    // open file at end 
    std::ifstream ifs(filename, std::ios::binary|std::ios::ate); 

    // calculate file size and move to beginning 
    auto end = ifs.tellg(); 
    ifs.seekg(0, std::ios::beg); 
    auto beg = ifs.tellg(); 

    // preallocate the string 
    std::string out; 
    out.reserve((end - beg) * 2); 

    char buf[2048]; // larger = faster (within limits) 

    while(ifs.read(buf, sizeof(buf)) || ifs.gcount()) 
    { 
     for(std::streamsize i = 0; i < ifs.gcount(); ++i) 
     { 
      out += to_hex(static_cast<unsigned char>(buf[i]) >> 4); // top nibble 
      out += to_hex(static_cast<unsigned char>(buf[i]) & 0b1111); // bottom nibble 
     } 
    } 

    return out; 
} 

그것은 복사를 최소화하고 재 할당을 피하기 위해 미리 할당 된 문자열에 추가합니다.

+0

자세한 해결책은 @Galik입니다. 이 접근법으로 얼마나 놀라운 성능 향상을 보였습니까? – Xigma

관련 문제