다음 DNA에서 C/C++에서 integer변수 swap 방법 비교 (http://dna.daum.net/technote/ccpp/CPPSwap) 라는 글을 보고 옛날 생각도 나고, 요즘 CPU 환경에서는 그냥 임시변수를 선언하여 구현하는 것이 더 빠르다는 결론이 재밌어 보여 윈도우에서도 함 해봤다.. VC++ 6.0과 VS 2008을 사용하여 2개를 비교를 해봤다..

원문에서 소개된 소스코드를 아래와 같이 조금 수정해봤다.. 윈도우즈 환경에서 실행시간 위해 약간의 코드를 추가했다.. 원본 코드는 그대로 유지했음.. 새 컴파일러가 좀 더 좋아진 점이 있는가 해서 VC++ 6.0과 VS 2008을 가지고 두번 비교를 해봄..


std::swap을 사용하는 방법
std::swap : c++에서 일반적으로 가장 널리쓰이는 안전한 방법

#include "stdafx.h"

#include <iostream>
#include <algorithm>
#include <stdio.h>

#include <windows.h>

int main(void)
{
    DWORD start = ::GetTickCount() ;

    int a = 1;
    int b = 2;
    for(int i=0;i<50000000;i++)
    {
        std::swap(a,b);
    }
   
    printf("%d %d\n\n",a, b);

    DWORD end = ::GetTickCount() ;
    printf("execution time : %1.3f m/s\n", (double)(end - start) / (double)100) ;

    int temp ;
    std::cin >> temp ;

    return 0 ;
}

VC++ 6.0 : execution time : 0.630 m/s
VS 2008 : execution time : 0.630 m/s


xor를 이용한 방법
c에서 예전에 많이 사용되던 방법 임시변수를 사용하지 않아서 좋다는 장점이 있음. 오래된 CPU에서는 이 방법이 빨랐으나 최근 CPU에서는 bit operation이 느려서 그다지 좋지 않다고 알려져있음.

#include "stdafx.h"

#include <iostream>
#include <algorithm>
#include <stdio.h>

#include <windows.h>

#define SWAP(a,b) { if (a!=b) { a^=b; b^=a; a^=b; }}

int main(void)
{
    DWORD start = ::GetTickCount() ;

    int a = 1;
    int b = 2;
    for(int i=0;i<50000000;i++)
    {
        SWAP(a,b);
    }
   
    printf("%d %d\n\n",a, b);
   
    DWORD end = ::GetTickCount() ;
    printf("execution time : %1.3f m/s\n", (double)(end - start) / (double)100) ;
   
    int temp ;
    std::cin >> temp ;
   
    return 0 ;
}

VC++ 6.0 : execution time : 0.940 m/s
VS 2008 : execution time : 0.940 m/s


임시변수를 이용한 방법
가장 기본적인 방법. 임시변수를 사용한다는 단점이 있음.

#include "stdafx.h"

#include <iostream>
#include <algorithm>
#include <stdio.h>

#include <windows.h>

#define SWAP(a,b) { int t=a; a=b; b=t; }

int main(void)
{
    DWORD start = ::GetTickCount() ;

    int a = 1;
    int b = 2;
    for(int i=0;i<50000000;i++)
    {
        SWAP(a,b);
    }
   
    printf("%d %d\n\n",a, b);
   
    DWORD end = ::GetTickCount() ;
    printf("execution time : %1.3f m/s\n", (double)(end - start) / (double)100) ;
   
    int temp ;
    std::cin >> temp ;
   
    return 0 ;
}

VC++ 6.0 : execution time : 0.470 m/s
VS 2008 : execution time : 0.630 m/s


결론
실험환경 : Intel Core2 Duo T5600 1.83GHz, 2.5GB RAM

VC++ 6.0 : execution time : 0.630 m/s
VS 2008 : execution time : 0.630 m/s

VC++ 6.0 : execution time : 0.940 m/s
VS 2008 : execution time : 0.940 m/s

VC++ 6.0 : execution time : 0.470 m/s
VS 2008 : execution time : 0.470 m/s

VC++ 6.0과 VS 2008의 차이점은 없음 (옵션 변경 없이 디폴트로 실행시켰을때..)
임시변수를 사용하는 방법이 가장 빠름.. 이상한 점은 VS 2008에서는 세번째 실험방법의 결과가 실행시마다 왔다갔다 한다는 점.. 0.470과 0.630이 실행시마다 왔다갔다 함..

새로운 환경에서는 예전의 지식은 힘을 발휘하지 못하게 되는 경우가 있다.. 임시변수를 두면 좋지 않다는 생각을 가지고 살다, 이런 결론을 얻고 보면 좀 황당하다.. std::swap 보다도 임시변수를 사용하는 것이 빠르다니.. 많이 읽고 정보를 수집하고, 직접 실습을 해보고 하여 항상 최신 지식으로 무장할 필요가 있다..

Posted by 미친병아리

댓글을 달아 주세요

  1. 한번쯤은.. 2008.11.01 14:11  댓글주소  수정/삭제  댓글쓰기

    안녕하세요
    프로그래머를 업으로 살고 있는 사람입니다.
    저도 한창 공부할때 님 처럼 많이 테스트 해보고 비교 해보고
    그것을 통해서 많은 것을 깨우치고 새로운 것을 많이 배웠답니다.

    만약 C/C++ 프로그래머시고 저보다 훨신 뛰어난 분이신지도 모르지만..
    감히 한마디 하자면..

    문득 이런 생각이 들더군요.
    위에서 비교하신 것처럼 연산 5천만번 수행하는데 겨우 최대로 0.47초 차이라면,
    과연 그게 실제 개발에 어떤 영향을 미칠까요?

    이렇게 테스트 비교하여 더 좋은 것을 습관적으로 사용하는건 분명이 좋겠지요..

    그렇지만 이런 미묘한 차이에 시간을 쓰는것 보다 원할하지 못한 전체적인 흐름을
    먼저 보는게 더 중요 하지 않을까요?

    구조 자체에 불필요한 연산이 증가한다면 거기서 오는 연산의 시간은 0.1초라도 아까운 시간이 되니까요. 거기에서 읽어버리는 시간을 잡는것이 더 중요하단 생각이 드네요..

    • 날라리 코더 2009.06.15 09:26  댓글주소  수정/삭제

      안녕하세요.
      미친병아리님 글은 6~7년전에 news.microsoft 에서 종종 읽어보곤 했었는데, 블로그에는 첨 찾아왔습니다.

      한번쯤은 님 글은 충분히 공감이 가네요.

      그런데 미친병아리님의 글은 개발의 Tip 또는 information 이라 볼 수 있고,

      한번쯤은 님의 글은 개발/개선에 임하는 자의 논리적 우선순위(또는 자세?)를 말하는 글이라 보이는데

      둘을 비교해서 무었이 더 중요하다고 말하는건 김치와 usb 메모리를 비교하는 것과 같다고 생각이 드네요.

      더 중요한것은 언제나 경우와 때에 따라 상대적인 것이죠. ^^

    • 신희운 2011.04.30 16:15  댓글주소  수정/삭제

      오만하군요.