문제

후에는 일부를 수행하는 테스트는 것으로 나타났 printf 보다 훨씬 더 빠르 cout.내가 알고있는 그것의 구현은 의존하지만,내에서 리눅스 printf 입니다 8 배 더 빠릅니다.그래서 나의 생각은 두 가지를 혼합한 인쇄방법:을 사용하고 싶 cout 에 대한 간단한 인쇄물,그리고 나는 계획을 사용하기 printf 생산을 위한 거대한 출력(일반적으로는 루프에서).내가 안전하다고 생각하지로 나가는 것을 잊지 않을 세척하기 전에 전환하는 다른 방법:

cout << "Hello" << endl;
cout.flush();

for (int i=0; i<1000000; ++i) {
    printf("World!\n");
}
fflush(stdout);

cout << "last line" << endl;
cout << flush;

그것은 좋아요?

업데이트: 에 대한 감사는 모든 소중한 피드백.요약의 답변:만약 당신이 피하고 싶은 까다로운 솔루션은 단순히 사용하지 않는 endlcout 므로 플러시 버퍼를 사용한다.사 "\n" 대신 합니다.그것은 재미있을 수있는 경우를 생산 출력이 있습니다.

도움이 되었습니까?

해결책

직접적인 대답은 그렇습니다. 괜찮다는 것입니다.

많은 사람들이 속도를 향상시키는 방법에 대한 다양한 아이디어를 던져 버렸지 만 가장 효과적인 일치가 상당히 불일치 한 것 같습니다. 나는 적어도 어떤 기술이 무엇을했는지에 대한 몇 가지 아이디어를 얻기 위해 빠른 시험 프로그램을 작성하기로 결정했습니다.

#include <iostream>
#include <string>
#include <sstream>
#include <time.h>
#include <iomanip>
#include <algorithm>
#include <iterator>
#include <stdio.h>

char fmt[] = "%s\n";
static const int count = 3000000;
static char const *const string = "This is a string.";
static std::string s = std::string(string) + "\n";

void show_time(void (*f)(), char const *caption) { 
    clock_t start = clock();
    f();
    clock_t ticks = clock()-start;
    std::cerr << std::setw(30) << caption 
        << ": " 
        << (double)ticks/CLOCKS_PER_SEC << "\n";
}

void use_printf() {
    for (int i=0; i<count; i++)
        printf(fmt, string);
}

void use_puts() {
    for (int i=0; i<count; i++) 
        puts(string);        
}

void use_cout() { 
    for (int i=0; i<count; i++)
        std::cout << string << "\n";
}

void use_cout_unsync() { 
    std::cout.sync_with_stdio(false);
    for (int i=0; i<count; i++)
        std::cout << string << "\n";
    std::cout.sync_with_stdio(true);
}

void use_stringstream() { 
    std::stringstream temp;
    for (int i=0; i<count; i++)
        temp << string << "\n";
    std::cout << temp.str();
}

void use_endl() { 
    for (int i=0; i<count; i++)
        std::cout << string << std::endl;
}

void use_fill_n() { 
    std::fill_n(std::ostream_iterator<char const *>(std::cout, "\n"), count, string);
}

void use_write() {
    for (int i = 0; i < count; i++)
        std::cout.write(s.data(), s.size());
}

int main() { 
    show_time(use_printf, "Time using printf");
    show_time(use_puts, "Time using puts");
    show_time(use_cout, "Time using cout (synced)");
    show_time(use_cout_unsync, "Time using cout (un-synced)");
    show_time(use_stringstream, "Time using stringstream");
    show_time(use_endl, "Time using endl");
    show_time(use_fill_n, "Time using fill_n");
    show_time(use_write, "Time using write");
    return 0;
}

VC ++ 2013 (X86 및 X64 버전 모두)으로 컴파일 한 후 Windows에서 이것을 실행했습니다. 한 번의 실행 (디스크 파일로 리디렉션 된 출력 포함)에서 출력이 다음과 같습니다.

          Time using printf: 0.953
            Time using puts: 0.567
   Time using cout (synced): 0.736
Time using cout (un-synced): 0.714
    Time using stringstream: 0.725
            Time using endl: 20.097
          Time using fill_n: 0.749
           Time using write: 0.499

예상대로 결과는 다양하지만 흥미로운 점이 몇 가지 있습니다.

  1. Printf/Puts는 NUL 장치에 쓸 때 Cout보다 훨씬 빠릅니다.
    • 하지만 Cout은 실제 파일에 쓸 때 꽤 멋지게 계속됩니다.
  2. 상당히 제안 된 최적화는 거의 달성하지 못했습니다
    • 내 테스트에서 Fill_n은 다른 것만 큼 빠릅니다.
  3. 지금까지 가장 큰 최적화는 ENDL을 피하는 것입니다
  4. cout.write는 가장 빠른 시간을 주었다 (아마도 큰 마진은 아니지만

최근에 코드를 편집하여 전화를 강제로 편집했습니다. printf. Anders Kaseorg는 지적하기에 충분히 친절했습니다 g++ 특정 시퀀스를 인식합니다 printf("%s\n", foo); 동일합니다 puts(foo);, 그에 따라 코드를 생성하고 (즉, 호출 할 코드를 생성합니다. puts 대신에 printf). 형식 문자열을 글로벌 배열로 이동하고 형식 문자열이 동일한 출력을 생성하지만 printf 대신에 puts. 물론, 그들은 언젠가 이것을 최적화 할 수 있지만 적어도 지금은 (G ++ 5.1) g++ -O3 -S 실제로 호출 중인지 확인합니다 printf (이전 코드가 호출로 컴파일 된 경우 puts).

다른 팁

배상 std::endl 스트림에 추가 a newline 스트림을 플러시합니다. 후속 호출 cout.flush() 불필요합니다. 타이밍이 완료된 경우 cout vs. printf 그런 다음 사과를 사과와 비교하지 않았습니다.

기본적으로 C 및 C ++ 표준 출력 스트림은 동기화되므로 하나에 쓰기가 다른 플러시를 유발하므로 명백한 플러시가 필요하지 않습니다.

또한 C ++ 스트림은 C 스트림과 동기화됩니다.
따라서 동기화를 유지하는 데 추가 작업이 수행됩니다.

주목해야 할 또 다른 것은 스트림을 같은 양으로 플러시하는 것입니다. 한 시스템에서 스트림을 지속적으로 플러시하면 테스트 속도에 확실히 영향을 미치는 다른 시스템이 아닌 다른 시스템이 아닙니다.

하나가 다른 것보다 빠르다고 가정하기 전에 :

  • CI/O의 UN-SYNC C ++ I/O (sync_with_stdio () 참조).
  • 플러시의 양이 비슷한 지 확인하십시오.

성능을 더욱 향상시킬 수 있습니다 printf 버퍼 크기를 증가시켜 stdout:

setvbuf (stdout, NULL, _IOFBF, 32768);  // any value larger than 512 and also a
                  // a multiple of the system i/o buffer size is an improvement

I/O를 수행하기 위해 운영 체제에 대한 호출 수는 거의 항상 가장 비싼 구성 요소 및 성능 리미터입니다.

당연하지 만약 cout 출력은 혼합되어 있습니다 stdout, 버퍼 플러시는 버퍼 크기가 증가한 목적을 물리칩니다.

당신이 사용할 수있는 sync_with_stdio C ++ IO를 더 빨리 만들기 위해.

cout.sync_with_stdio(false);

출력 성능을 향상시켜야합니다 cout.

에 대해 걱정하지 마십시오 성능을 사 printfcout.을 얻을하려는 경우의 성능,분리되는 포맷 출력에서 포맷 출력.

puts("Hello World\n") 보다 훨씬 더 빠르 printf("%s", "Hellow World\n"). (주로 인해 서식 오버헤드). 면 당신은 고립 된 이 포맷에서 일반 텍스트를 수행할 수 있습니 tricks like:

const char hello[] = "Hello World\n";
cout.write(hello, sizeof(hello) - sizeof('\0'));

속도 포맷 출력을,트릭은 수행하는 모든 형식 문자열,다음 사용 블록을 출력 문자열로(또는 버퍼):

const unsigned int MAX_BUFFER_SIZE = 256;
char buffer[MAX_BUFFER_SIZE];
sprintf(buffer, "%d times is a charm.\n", 5);
unsigned int text_length = strlen(buffer) - sizeof('\0');
fwrite(buffer, 1, text_length, stdout);

를 더욱 개선하는 프로그램의 성능,수량을 줄일 수 출력합니다.더 적은 물건을 출력,더 빨리 프로그램이 될 것입니다.부작용이 있는 실행 파일 크기의 축소됩니다 너무입니다.

글쎄, 나는 Cout을 실제로 정직하게 사용해야 할 이유를 생각할 수 없습니다. 모든 파일에있을 정도로 간단한 일을하기 위해 거대한 부피가 큰 템플릿을 갖는 것은 완전히 미쳤다. 또한 가능한 한 느리게 입력하도록 설계되었으며 백만 번째 타이핑 <<<< 이후에 <<<< 다음 사이에 값을 입력하고 LIK> variableName >>>를 얻는 것과 같은 값을 입력 한 후에는 다시는 그렇게하고 싶지 않습니다. .

당신이 STD 네임 스페이스를 포함 시키면 말할 것도없이 세계는 결국 사라질 것이며, 입력 부담이 더욱 말도 안됩니다.

그러나 나는 printf를 많이 좋아하지 않습니다. 나를 위해, 해결책은 내 자신의 콘크리트 클래스를 만들고 그 안에 필요한 물건을 부르는 것입니다. 그런 다음 원하는 방식으로, 원하는 구현, 원하는 형식 등으로 정말 간단한 IO를 가질 수 있습니다 (일반적으로 플로트는 항상 한 가지 방법이되기를 원합니다. 모든 통화와 함께 서식하는 것은 농담입니다).

그래서 내가 입력 한 것은 "+debugiotype+"의 "+cplusplusmethod+"보다 더 세인됩니다. IMO는 적어도 "; dout ++;

그러나 당신은 당신이 원하는 것을 가질 수 있습니다. 많은 파일을 사용하면 컴파일 시간을 얼마나 향상시키는 지 놀랍습니다.

또한 C와 C ++를 믹싱하는 데 아무런 문제가 없으며, 단순히 수행해야하며, C를 사용하는 데 문제를 일으키는 것들을 사용하는 경우 처음에 C를 믹싱하는 데 어려움을 겪는 것이 안전합니다. C ++.

C ++와 C Iomethods를 혼합하는 것은 C ++ 책인 FYI에 대해 권장했습니다. 나는 C 함수가 C ++가 예상/보유 한 상태에 대한 트래려를 확신합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top