본문 바로가기
코딩/C 언어

c언어 코드 최적화 3장. LOOP 최적화

by DIYver 2020. 10. 14.

코드를 짜다보면 반복문은 무조건 사용하게 되어있다.

그런데 이 반복문 연산속도가 빠른놈이 아니다.

 

 

1. 반복문은 연산속도가 느리다.

 

반복을 하게되면 연산속도가 늦다는 것인데,

예를 들면 

1부터 n까지의 정수들으 더하는 코드를 작성하면 아래와 같을 것이다.

for(int i = 1; i<=n; i++)
{
	sum += i;
}

정말 간단하고 명료하다.

 

하지만 우리는 중학교 수학시간에 이러한 경우 공식이 있다는 것을 배웠다.

가우스 덧셈공식이라고 불러야하나?

 

아무튼 공식에 의하면 코드는 아래와 같이 사용할 수 있겠다.

 

sum = (n+1)*n/2 ;

이것도 엄청 간단 명료하다.

 

나눗셈을 사용하지 말라고 했었으면서, 공식에 나눗셈이 들어간 아이러니한 상황...ㅎㅎ

컴파일러가 똑똑해져서 2의 멱수 로 나눈 경우 쉬프트연산으로 하지 않을까 싶다.

 

위의 두 경우 어느 방법이 더 연산속도가 빠를지 알아보자.

 

 

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

void main()
{
	clock_t start, end;
	float res;
	start = clock();
	int sum = 0;

	for (int i = 0; i < 100000000; i++)
	{
		sum += i;
	}
	printf("더한 값 : %d \n", sum);

	end = clock();
	res = (float)(end - start) / CLOCKS_PER_SEC;

	printf("\n소요시간 : %.3f \n", res);
	return;
}

반복문을 이용한 결과는 

평균적으로 0.239 초 정도 소요되었다.

꽤 오래걸렸다...

 

 

 

 

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



void main()
{
	clock_t start, end;
	float res;
	start = clock();
	int sum = 0;

	int n = 100000000;

	sum = (n+1)*n/2;
	printf("더한 값 : %d \n", sum);

	end = clock();
	res = (float)(end - start) / CLOCKS_PER_SEC;

	printf("\n소요시간 : %.3f \n", res);
	return;
}

공식을 이용한 경과는

놀랍게도

연산처리에 시간이 거의 소모되지 않았다.

그냥 즉답이 나왔다.

 

 

이처럼 반복문은 사용하지 않을 수 있다면

사용하지 않는것이 좋다.

 

물론 필요하다면 사용해야 하지만,

1ms 의 연산속도를 다퉈야한다면 반복문을 줄이는 과정은 필수적이어야 할 것이다.

 

 

 

 

 

 

2. 반복문 한번 돌 때 많은 연산을 하자.

 

반복문이 속도가 느린 이유는, 한번 돌고 다시 처음으로 돌아가서 시작하는 것 때문이다.

그러니깐 반복문을 사용할 때에는 반복 횟수를 줄이는 것이 좋다는 것이다.

 

이 역시 실제로 테스트를 해봐야 체감이 될 것이다.

 

앞에서 다뤘던 N까지 수를 더하는 반복문에서

반복을 할 때 연산을 여러번 해보도록 하고,

시간이 얼마나 단축되는지 확인해보자.

 

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



void main()
{
	clock_t start, end;
	float res;
	start = clock();
	int sum = 0;

	int n = 100000000;
	for (int i = 1; i <= 100000000; i+=2)
	{
		sum += (i+i+1);
	}
	printf("더한 값 : %d \n", sum);

	end = clock();
	res = (float)(end - start) / CLOCKS_PER_SEC;

	printf("\n소요시간 : %.3f \n", res);
	return;
}

위에서 다뤘던 코드에서

반복되는 횟수를  1억번에서 5천만번으로 줄였다.

증감을 i +=2 로 바꾸었고, sum+= i+ (i+1) 로 바꾸었다.

 

결과는 이론상으로 따지면 1억번 반복했을때 시간인 0.239의 절반인

0.120 정도가 나와야 한다.

 

정말 놀랍게도 결과가 이론대로 나왔다.

소요시간이 0.120 이 나왔다.

 

 

 

 

 

그러면 반복문이 한번 돌 때 4번 연산을 하면 4배 빨라지는 것일까?

 

이것 역시 직접 실험해 보도록 하자.

 

4배 빨라지는 것이라면 이론상으로 0.239의 4분의 1인 0.060 초가 걸려야 한다.

 

 

정말 흥미롭게도 거의 이론상 수치대로 연산시간이 걸린 것을 볼 수 있다.

같은 결과를 도출해내는데, 연산시간이 이렇게 달라질 수 있을까 싶다.

그냥 별 생각없이 코딩한 반복문은 0.239 초가 걸렸는데,

간단한 최적화 방법을 적용하였더니 시간이 0.063 초로 줄어들었다.

 

 

 

 

물론... 반복문을 사용하지 않고 사칙연산으로 할 수 있는 방법이 있다면 

그 방법이 제일 좋은 방법이다...

 

결론은 

1. 반복문은 느리다.

2. 반복문 사용 시에는 한번에 많은 연산을 한꺼번에 돌려야 좋다.

 

 

 

 

 

 

<이전 글>

1.  c언어 코드 최적화 1장. 나눗셈을 사용하지 말자.

 

c언어 코드 최적화 1장. 나눗셈을 사용하지 말자.

C언어는 오랜 역사를 갖고 있으며, 더 발전한 C++ 언어 역시 많은 곳에서 사용되고 있다. 특히 컴퓨터보다는 제한된 성능의 기계에서 사용하고는 한다. 보통 우리는 임베디드 시스템이라고 부른��

diyver.tistory.com

 

2. C언어 코드 최적화 2장. 비트연산을 사용하자.

 

C언어 코드 최적화 2장. 비트연산을 사용하자.

C언어 코드 최적화 방법은 여러가지가 있다. 이전에 나눗셈을 사용하지 않는것을 다뤄봤었다. 이번에는 비트연산을 사용하는 것이 얼마나 빠르게 코드를 작동시키는지 다뤄보도록 하자. 비트(bi

diyver.tistory.com

 

댓글