C언어로 화면에 abc를 출력해내는 가장 빠른방법

stargt의 이미지

C언어에는 문자열을 출력하는 다양한 함수가 있습니다.

그런데 과연, 이 함수들이 속도가 모두 같을까요?

어떤 함수로, 어떤 방식으로해야 다른것보다 빨리 출력될까요?

또, 이것들은 다른언어들 보다 빠른것일까요?

scheinx의 이미지

C 언어랑 어셈블리로 hellow world c 문자를 출력하는 프로그램을 만들었는데 용량차이가 많이 나던데.. 속도 측정 방법을 몰라서 속도측정은 못해봤네요.. 아마도 용량이 적은 만큼 빠를지도..ㅋ

7339989b62a014c4ce6e31b3540bc7b5f06455024f22753f6235c935e8e5의 이미지

glibc 소스에서 printf 함수 선언을 추적해보세요. :)

앙마의 이미지

abc를 출력하는 방법이 다양할텐데 clock()함수를 사용하여 각각의 clock시간을 알아내어 비교해 보면 될 것 같습니다. 그런데 문제점이 clock시간이 제대로 나와줄지 의문이군요. 0으로 나올지도 모르겠네요. 그리고 clock시간은 정확하지 않아 시간 비교를 위해 사용하는 것은 유용하지만 절대적인 시간값을 알아내는데는 유용하지 못할겁니다.

autography

인간에게는 자신의 운명을 거부할 권리가 있다.

bus710의 이미지

생성된 바이너리의 크기를 보면 되지 않을까요?

바이너리 사이즈가 크면 CPU에 로드되는 명령어가 많다는 뜻이고.... 동일한 출력일지라도 그만큼 최종 결과 수행은 느리다는 말인 고로...

사이즈가 크게 생성되는 코드가 느린 코드다... 라고 볼 수 있겠죠?

life is only one time

prolinko의 이미지

표준 posix 시스템의 경우 file descriptor를 이용하는 저수준 IO가 있고 ANSI C에는 이를 wrapping 하여서 buffering을 하는 고수준 IO 함수들(standard library)이 구현되어있습니다. 이 함수들은 fd와 여러 값들을 wrapping하는 FILE* 핸들러를 사용합니다.

각각의 예를 든다면.

write(STDOUT_FILENO, "abc", 3);

fpust("abc", stdout);

standard library에서 저수준 함수들을 불러다 사용할 것이므로 하나의 call에 대해서는 당연히 저수준 IO가 빠르겠지만, 이는 의미 없다고 생각합니다. 실제 IO의 속도가 사용자가 느낄 수 있을 만큼되려면 연속적인 IO가 이루어질 경우이고 이 경우에는 매번 write를 부르는 것보다 buffering을 하는 FILE* 형식의 standard library가 더 낳은 성능을 보여주기 때문입니다. (그리고 이것이 고수준 IO를 사용하는 이유 중 하나입니다.)

park712의 이미지

글 안 쓰려고 하다가 한 줄 남겨 봅니다.

CPU 시간은 퀀텀단위입니다.
그리고, 그 퀀텀을 측정하는 함수가 있습니다.
함수를 이용해 측정가능합니다. 하지만, 예제처럼 짧은 경우는 퀀텀 측정이라는게 무의미 합니다.
더구나 CPU 시간측정 함수자체의 결함으로 완벽한 시간측정은 불가능합니다.
CPU 와 HDD 등 제반 환경에 따라 실행시 미세한 차이가 있는것이 정상이나
실제 시간측정 단위가 적은경우는 무의미 합니다.
동일한 환경에서 계속 프로그램을 실행하고 시간 측정해도 그 결과(퀀텀)는 다를 수 있습니다

main()
{
시간측정 시작;

연산처리;

시간측정종료 및 출력;

}

항상 동일한 값이 나와야 정상이나 차이가 있을 수 있습니다.

추가:글 표현 속도 문제가 질문이군요 그건 직접 측정해 보시는게 좋을 듯 하지만, 무의미할 것으로 생각합니다. 문자 표현속도로 고민하는 분을 못 봤습니다. 요즘 메모리 가격도 낮고 CPU속도가 무식하기 빠르기에 고민대상이 안되는것으로 알고 있습니다.

후회없이 살자

seoleda의 이미지

짧은 시간을 측정하는 다음과 같은 방법도 있습니다.

start_time = time();
for (i=0; i<BIGNUM; i++){
측정할 함수호출();
}
end_time = time();
time = (end_time - start_time)/BIGNUM;
perky의 이미지

요새는 I/O보다 화면의 폰트 드로잉이 훨씬 더 비싼 작업입니다.
따라서, I/O 쪽에서 느린 것을 쓴다고 해도, 폰트 드로잉 부분을
구식 텍스트 화면을 쓰면 빠를 것이고.. I/O를 zero copy로 구현하는 등
아무리 용을 써도 화면 표시 부분에서 gnome-terminal을 쓰면 느립니다.

libc 함수들은 대개 굉장히 간단하고 모듈화가 잘 되어 있기 때문에,
뭔가 궁금한 것이 있으면, 소스를 보는 것이 무엇보다 더 자세하고
빠르게 알 수 있는 방법입니다.

You need Python

seoleda의 이미지

심심해서 함 측정해 봤습니다. 제 예상으로는 asm으로 int 0x80을 직접 호출하는 것이 printf함수를 사용하는 것보다 빠를 것이라고 생각했는데, printf가 한 4배 정도 빠르군요.

asm: 0.055000ms, printf: 0.015000ms
버퍼링을 가만해서, msg를 "abc\n"으로 해도 printf가 한 2배 정도 빠르더군요.

실험한 코드는 다음과 같습니다.

#include <stdio.h>
#include <time.h>

#define MAX 200000
char* msg = "abc";
int l = 4;
void asmprint(){
        __asm__ __volatile__ (
                        "movl $1, %%ebx         \n\t"
                        "movl $4, %%eax         \n\t"
                        "int $0x80              \n\t"
                        :
                        :"d"(l), "c"(msg));
}

int main(int argc, char* argv[]){
        int i;
        time_t start, end;
        float t1, t2;
        start = time(0);
        for (i=0; i<MAX; i++){
                asmprint();
        }
        end = time(0);
        t1 = (float)(end-start)/(float)MAX*1000;

        start = time(0);
        for (i=0; i<MAX; i++){
                printf("%s", msg);
        }
        end = time(0);
        t2 = (float)(end-start)/(float)MAX*1000;
        printf("asm: %fms, printf: %fms\n", t1, t2);
        return 0;
}