다음 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 미친병아리