본문 바로가기

Eureka/Coding

[Calculation Speed Test] Left-Shift Operate & Assignment Operate

[연산 속도 테스트]

쉬프트 연산(<< or >>), 대입 연산(=)


[개요]
정말 궁금해서 한번 테스트를 해봤는데요...
어떤 연산이 더 빠른가 였습니다.



[과정]
1. Left-Shift 연산 10,000,000 (일천만)번
2. Assignment 연산 10,000,000 (일천만)번
3. 각각 연산 하는 동안의 시간을 마이크로초(1/1,000,000초)로 계산
4. 위의 과정을 100번 수행 후 평균 시간 값을 출력


[동일조건]
1. 변수의 최종결과 값
2. loop의 횟수


[고려하지 않은 조건]
1. loop 진행하는 동안에 딜레이 되는 시간


[연산속도에 영향을 미치는 요인]
1. 자료형
    32비트 머신에서는 32비트 자료형이 최적의 연산속도를 보장하고,
    64비트 머신에서는 64비트 자료형이 최적의 연산속도를 보장한다. 

    예를들어 64비트 머신에서는 64비트 단위로 메모리를 조작하게 된다.

    즉, 64비트 자료형을 사용하면 하나의 오퍼레이션으로 변수를 불러올 수 있다.
    32비트 자료형을 사용하게 되면, 64비트를 불러와서 다시 32비트를 분리하는 오퍼레이션(shift)이 추가된다.

2. 루프의 형태
    루프 작업의 경우 어찌하든 조건비교 연산이 추가되므로 때에 따라서는 지저분한 코드가 나을수도 있다.


3. 컴파일러 및 컴파일러 옵션
    컴파일러가 알아서 최적의 코드로 바꿔주기도 한다.
    즉, 결과는 원하는 결과가 나오지만, 연산과정은 원하던 과정이 아닌 더욱 최적화된 과정으로 변경될 수도 있다.



[결과]

▲ shift 연산이 더 오래 걸렸습니다.
(반전 결과는 루프의 횟수가 낮을 때 shift 연산이 좀 더 빠른 결과를 내기도 하더군요, 환경요인의 오차라고 생각합니다)



[테스트 소스]

#include <windows.h>

#include <stdio.h>

 

__int64 GetMicroSecond();

int Shift_Operate();

int Assignment_Operate();

 

int main(int argc, char* argv[])

{

        int sh_avg[100] = {NULL};

        int as_avg[100] = {NULL};

        int sum_avg1 = 0;

        int sum_avg2 = 0;

 

        for(int i = 0; i < 100; i++) {

                sh_avg[i] = Shift_Operate();

               as_avg[i] = Assignment_Operate();

        }

        for(int i = 0; i < 100; i++) {

               sum_avg1 += sh_avg[i];

               sum_avg2 += as_avg[i];

        }

 

        printf("Left Shift Operate Average Time( Performed 100 times ) : %dus\n", sum_avg1 / 100);

        printf("Assigment  Operate Average Time( Performed 100 times ) : %dus\n", sum_avg2 / 100);

 

        return 0;

}

 

__int64 GetMicroSecond()

{

        LARGE_INTEGER frequency;

        LARGE_INTEGER now;

 

        if ( !QueryPerformanceFrequency(&frequency) )

               return (__int64)GetTickCount();

 

        if ( !QueryPerformanceCounter(&now) )

               return (__int64)GetTickCount();

 

        return ((now.QuadPart) / (frequency.QuadPart/1000000));

}

 

int Shift_Operate() {

        __int64 tStart = 0;

        int num = 10;

        int i = 0;

        tStart = GetMicroSecond();

        for(i = 0; i < 10000000; i++)  {

               num << 10;

               num >> 10;

        }

 

        return GetMicroSecond() - tStart;

}

 

int Assignment_Operate() {

        __int64 tStart = 0;

        int num = 10;

        int i = 0;

        tStart = GetMicroSecond();

        for(i = 0; i < 10000000; i++)  {

               num = 10240;

               num = 10;

        }

 

        return GetMicroSecond() - tStart;

}



[소스 다운로드]

Calculation_Speed_Test.cpp