문제

내가 발견한 경우 인쇄 긴 문자열(char*)를 사용하여 cout 것 인쇄 1 문자에서 시간에 화면 윈도우 7,비스타,리눅스를 사용하여(putty)을 이용하여 Visual C++2008Windows,G++리눅스에서.Printf 이 너무 빨리 내가 실제로 전환 cout 을 printf 대부분의 인쇄에서 프로젝트입니다.이것은 나를 혼란 때문에 이 질문 처럼 보이는 내 하나만을 이 문제를 해결합니다.

도 썼 cout 교체하는 것처럼 보인 비트 떨어져 바지 cout 에 comp

class rcout
{
public:
    char buff[4096];
    unsigned int size;
    unsigned int length;

    rcout()
    {
        size = 4096;
        length = 0;
        buff[0] = '\0';
    }

    ~rcout()
    {
        printf("%s", buff);
    }

    rcout &operator<<(char *b)
    {
        strncpy(buff+length, b, size-length);
        unsigned int i = strlen(b);
        if(i+length >= size)
        {
            buff[size-1] = '\0';
            printf("%s", buff);
            b += (size-length) -1;
            length = 0;
            return (*this) << b;
        }
        else
            length += i;
        return (*this);
    }

    rcout &operator<<(int i)
    {
        char b[32];
        _itoa_s(i, b, 10);
        return (*this)<<b;
    }

    rcout &operator<<(float f)
    {
        char b[32];
        sprintf_s(b, 32, "%f", f);
        return (*this)<<b;
    }
};

int main()
{
    char buff[65536];
    memset(buff, 0, 65536);

    for(int i=0;i<3000;i++)
        buff[i] = rand()%26 + 'A';

    rcout() << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
    Sleep(1000);
    cout << "\n\nOk, now cout....\n\n";
    cout << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
    Sleep(1000);
    cout << "\n\nOk, now me again....\n\n";
    rcout() << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
    Sleep(1000);

    return 0;
}

어떤 아이디어를 왜 cout 인쇄 천천히니까?

도움이 되었습니까?

해결책

노트:이 실험 결과는 MSVC에 유효합니다. 다른 라이브러리 구현에서는 결과가 다릅니다.

printf ~할 수 있었다 (많이) 더 빠릅니다 cout. 하지만 printf 런타임에서 형식 문자열을 구문 분석하면 기능 호출이 훨씬 적고 실제로 동일한 작업을 수행하기 위해 적은 수의 명령어가 필요합니다. cout. 다음은 내 실험의 요약입니다.

정적 명령의 수

일반적으로 cout 보다 많은 코드를 생성합니다 printf. 우리는 다음을 가지고 있다고 말합니다 cout 일부 형식으로 인쇄 할 코드.

os << setw(width) << dec << "0x" << hex << addr << ": " << rtnname <<
  ": " << srccode << "(" << dec << lineno << ")" << endl;

최적화가있는 VC ++ 컴파일러에서 188 바이트 코드. 그러나 교체 할 때 printf-기반 코드 만 42 바이트가 필요합니다.

동적으로 실행 된 명령의 수

정적 명령의 수는 정적 이진 코드의 차이를 알 수 있습니다. 더 중요한 것은 런타임에서 동적으로 실행되는 실제 명령 수입니다. 나는 또한 간단한 실험을했다 :

테스트 코드 :

int a = 1999;
char b = 'a';
unsigned int c = 4200000000;
long long int d = 987654321098765;
long long unsigned int e = 1234567890123456789;
float f = 3123.4578f;
double g = 3.141592654;

void Test1()
{
    cout 
        << "a:" << a << “\n”
        << "a:" << setfill('0') << setw(8) << a << “\n”
        << "b:" << b << “\n”
        << "c:" << c << “\n”
        << "d:" << d << “\n”
        << "e:" << e << “\n”
        << "f:" << setprecision(6) << f << “\n”
        << "g:" << setprecision(10) << g << endl;
}

void Test2()
{
    fprintf(stdout,
        "a:%d\n"
        "a:%08d\n"
        "b:%c\n"
        "c:%u\n"
        "d:%I64d\n"
        "e:%I64u\n"
        "f:%.2f\n"
        "g:%.9lf\n",
        a, a, b, c, d, e, f, g);
    fflush(stdout);
}

int main()
{
    DWORD A, B;
    DWORD start = GetTickCount();
    for (int i = 0; i < 10000; ++i)
        Test1();
    A = GetTickCount() - start;

    start = GetTickCount();
    for (int i = 0; i < 10000; ++i)
        Test2();
    B = GetTickCount() - start;

    cerr << A << endl;
    cerr << B << endl;
    return 0;
}

Test1 (Cout)의 결과는 다음과 같습니다.

  • 실행 된 지침 : 423,234,439

  • 메모리 부하/저장 : 약. 320,000 및 980,000

  • 경과 시간: 52 초

그럼, 무슨 일이야 printf? 이것은 test2의 결과입니다.

  • 실행 된 지침 : 164,800,800

  • 메모리 부하/저장 : 약. 70,000 및 180,000

  • 경과 시간: 13 초

이 기계와 컴파일러에서 printf 훨씬 더 빨랐습니다 cout. 실행 된 지침의 수와로드/스토어 (캐시 미스의 #을 나타냄)에는 3 ~ 4 배의 차이가 있습니다.

나는 이것이 극단적 인 경우라는 것을 안다. 또한, 나는 그것을 주목해야합니다 cout 32/64 비트 데이터를 처리 할 때 훨씬 쉽고 32/64 플랫폼 독립성이 필요합니다. 항상 트레이드 오프가 있습니다. 사용 중입니다 cout 확인시 유형이 매우 까다 롭습니다.

괜찮아, cout MSV에서는 단지 짜증납니다 :)

다른 팁

다른 컴퓨터에서 동일한 테스트를 시도하는 것이 좋습니다. 왜 이런 일이 일어나고 있는지에 대한 좋은 대답이 없습니다. 내가 말할 수있는 것은 Cout과 Printf의 속도 차이를 본 적이 없다는 것입니다. 또한 Linux에서 GCC 4.3.2를 사용하여 코드를 테스트했으며 차이가 없었습니다.

즉, Cout을 자신의 구현으로 쉽게 대체 할 수는 없습니다. 사실, Cout은 STD :: Ostream의 인스턴스입니다. 많이 ioStream 연산자에 과부하가 걸리는 다른 클래스와 상호 운용성에 필요한 기능이 내장되어 있습니다.

편집하다:

말하는 사람 printf 항상보다 빠릅니다 std::cout 간단합니다 잘못된. 방금 64 비트 AMD Athlon X2의 GCC 4.3.2 및 -o2 플래그와 함께 Minjang이 게시 한 테스트 코드를 실행했으며 Cout은 실제로였습니다. 더 빠르게.

다음 결과를 얻었습니다.

printf: 00:00:12.024
cout:   00:00:04.144

Cout은 항상 printf보다 빠릅니까? 아마 그렇지 않을 것입니다. 특히 구현 구현은 아닙니다. 그러나 최신 구현에서 ioStream은 런타임에 형식 문자열을 구문 분석하는 대신 컴파일 시간에 정수/부동/객체를 문자열로 변환하기 위해 어떤 기능을 호출 해야하는지 알고 있기 때문에 ioStream은 stdio보다 빠를 수 있습니다.

그러나 더 중요한 것은 printf 대 cout의 속도 구현에 따라 다릅니다, 따라서 OP가 묘사 한 문제는 쉽게 설명 할 수 없습니다.

전화 해보세요 ios::sync_with_stdio(false); std :: cout/cin을 사용하기 전에, 물론, 당신은 당신의 프로그램에서 stdio와 iostream을 혼합하지 않으면, 이것은 나쁜 일입니다.

프로그래밍 경쟁에 대한 나의 경험을 바탕으로 Printf는 Cout보다 빠릅니다.

내 솔루션이 시간 제한 이전에 만들어지지 않았을 때를 여러 번 기억합니다. cin/cout, 동안 printf/scanf 일했다.

그 외에도, 그것은 정상적인 것 같습니다 (적어도 나를 위해) cout 보다 느립니다 printf, 더 많은 작업을 수행하기 때문입니다.

일부를 사용해보십시오 endls 또는 flush그들이 플러시 할 때 coutOS가 어떤 이유로 든 프로그램의 출력을 캐싱하는 경우의 버퍼. 그러나 Charles가 말했듯이,이 동작에 대한 좋은 설명은 없기 때문에 도움이되지 않으면 기계와 관련된 문제 일 수 있습니다.

기를 작성해 주시는 모든 데이터는 ostringstream 먼저,다음 사용 coutostringstreamko str().나 64-bit Windows7 Test1 이미보다 상당히 빠른 속도 Test2 (주 달라질 수 있습니다.)를 사용하는 ostringstream 을 구축하는 단 하나 문자열을 먼저 다음 사용 cout추가 감소 Test1아 실행 시간에 의해 요소의 약 3~4.야 #include <sstream>.

I.e., 대체

void Test1()
{
    cout
        << "a:" << a << "\n"
        << "a:" << setfill('0') << setw(8) << a << "\n"
        << "b:" << b << "\n"
        << "c:" << c << "\n"
        << "d:" << d << "\n"
        << "e:" << e << "\n"
        << "f:" << setprecision(6) << f << "\n"
        << "g:" << setprecision(10) << g << endl;
}

과:

void Test1()
{
    ostringstream oss;
    oss
        << "a:" << a << "\n"
        << "a:" << setfill('0') << setw(8) << a << "\n"
        << "b:" << b << "\n"
        << "c:" << c << "\n"
        << "d:" << d << "\n"
        << "e:" << e << "\n"
        << "f:" << setprecision(6) << f << "\n"
        << "g:" << setprecision(10) << g << endl;
    cout << oss.str();
}

I suspect ostringstream 이렇게 훨씬 더 빠른 결과적으로의하지 않을 작성하려고 하면 시간을 전화 operator<<cout.나타났습 경험을 통해하는 횟수가 줄 당신이 쓰기 화면(작성하여 더 번)증가능(을 다시,당신의 마일리지 달라질 수 있습니다.)

E.g.,

void Foo1()
{
    for(int i = 0; i < 10000; ++i) {
        cout << "Foo1\n";
    }
}

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

void Foo3()
{
    std::ostringstream oss;
    for(int i = 0; i < 10000; ++i) {
        oss << "Foo3\n";
    }
    cout << oss.str();
}

내 경우에, Foo1 했 1,092ms, Foo2 했 234ms 고 Foo3 했 218ms. ostingstreams 는 당신의 친구입니다.분명히 Foo2 및 Foo3 요구(사소)더 많은 메모리.을 비교하는 이에 대하여는 C 스타일의 기능도 sprintf 으로 버퍼를 작성하는 버퍼를 사용하여 fprintf 고 더 효율 Test2 (그러나 나를 위해 이것만의 성능 향상 Test2 에 의해 약 10%정도; coutprintf 실제로 다른 짐승 후드에서).

컴파일러:MinGW64(TDM 및 그에 포함된 라이브러리들).

사용해보십시오 ios::sync_with_stdio(false);. std :: cin/cout를 사용하기 전에 언급하십시오. Stdio 또는 ioStream을 혼합하지는 않지만 ioStream 표준 스트림을 해당 표준 C 스트림과 동기화합니다. 예를 들어 -STD :: CIN/WCIN의 iOStream은 C Stream의 stdin과 동기화됩니다.

다음은 c ++ 스트림을 c printf만큼 빠르게 만들어야하는 hax입니다. 나는 그것을 테스트하지 않았지만 그것이 작동한다고 생각합니다.

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