while(1)이랑 while(2)중 어 느게 더 빠르나요?


발생하는 문제 및 실행환경

면접에서 while(1)이랑 while(2)중 어느 게 더 빠를 것 같냐고 물어봐서 저는 (1)이던 (2)던 똑같이 true니까 둘이 같은 속도일 것 같다고 대답했는데 while(1)이 더 빠르다고 합니다. 왜죠?

소스코드

while(1) {
    //어떤 코드
}
or

while(2) {
    //어떤 코드
}
  • 2016년 01월 29일에 작성됨

조회수 318


1 답변


좋아요
0
싫어요
채택취소하기

두 개의 코드가 실제로 어떻게 실행되는지 보려면, gcc에서 두 코드의 어셈블리를 비교해야 합니다.

int main(void)
{
    while(1)
    {
    }

    return 0;
}


int main(void)
{
    while(2)
    {
    }

    return 0;
}

제가 돌려 본 결과로는 최적화옵션(-O0)유무에 상관없이 두 코드의 어셈블리는 같습니다. 그래서 두 반복문 사이에는 속도차가 없어요.

어떤 최적화에서도 (gcc main.c -S -masm=intel+옵션) 둘은 항상 같은 결과가 나왔습니다.

-O0에서:

    .file   "main.c"
    .intel_syntax noprefix
    .def    __main; .scl    2;  .type   32; .endef
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    push    rbp
    .seh_pushreg    rbp
    mov rbp, rsp
    .seh_setframe   rbp, 0
    sub rsp, 32
    .seh_stackalloc 32
    .seh_endprologue
    call    __main
.L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

-O1에서:

    .file   "main.c"
    .intel_syntax noprefix
    .def    __main; .scl    2;  .type   32; .endef
    .text
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    sub rsp, 40
    .seh_stackalloc 40
    .seh_endprologue
    call    __main
.L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

-O2/-O3에서:

    .file   "main.c"
    .intel_syntax noprefix
    .def    __main; .scl    2;  .type   32; .endef
    .section    .text.startup,"x"
    .p2align 4,,15
    .globl  main
    .def    main;   .scl    2;  .type   32; .endef
    .seh_proc   main
main:
    sub rsp, 40
    .seh_stackalloc 40
    .seh_endprologue
    call    __main
.L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

어떤 최적화 방식을 써도 반복문은 아래와 같은 형태인게 보이시나요?

 .L2:
    jmp .L2
    .seh_endproc
    .ident  "GCC: (tdm64-2) 4.8.1"

중요한 건 여기에서,

.L2:
    jmp .L2

제가 어셈블리어를 잘 하지는 못하지만, 이건 unconditional loop로 비교하는 것 없이 무조건 L2로 점프하는 입니다. 이걸 c코드로 바꾸면

L2:
    goto L2;

입니다.

요약해서 말하면, 반복문이 어셈블리 언어로 컴파일될 때, 반복문에 상수값이 있다면 컴파일러가 이걸 미리 처리해 버립니다.

따라서 while(1), while(2), while(1==1), while(3==3 && 4==4), while(0.1+0.2)등은 컴파일하면 전부 같은 어셈블리 코드가 되기 때문에 수행 속도에 차이가 없습니다.

  • 2016년 01월 29일에 작성됨

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close