프로그래밍 언어 공부/C

어플리케이션 최적화(Application Optimization)

CalebHong 2022. 1. 12. 12:16

최적화란?

- 정보공학에서 시스템을 수정하여 어떠한 면의 작업을 더 효과적으로, 또는 자원을 덜 사용하도록 만드는 작업

 

  • 컴퓨터 프로그램은 더 빠르게 실행되거나 기억 장치 또는 자원을 덜 차지하게 하여 운영하도록 개선
  • 유지보수의 편의성을 고려한 코드 개선
  • 안정성 확보를 위한 최적화

최적화 기법

- 성능 체크 : 최적화 대상 선정

- 코드 분석 : 최적화 향상

 

  1. 병목지점 찾기 (소요시간)
  2. 구조체 복사 시 대입연산자 대신 라이브러리 함수를 이용
  3. 구조체 전달은 포인터를 이용
  4. 함수의 매개변수를 축소 (4개 이하: 레지스터 이용, 4개 이상: 스택 이용)
  5. 4Byte 이상 전달 시 포인터를 이용
  6. 4개 이상인 경우 인자를 구조체로 선언하고 구조체 포인터를 매개변수로 전달
  7. const를 적절히 활용 (안정성 확보 차원)
  8. 2의 n 제곱을 곱하는 연산은 쉬프트 연산 수행
  9. 실수연산을 축소
  10. 소수점 이하 2자리까지만 필요한 연산 -> 실수의 연산에서 100을 곱한 후 연산을 해 100으로 나눔
  11. 지역변수를 최대한 활용
  12. 전역변수 사용을 최소화

매개변수 최적화

1. 구조체는 포인터로 전달

_example_최적화 전

struct text
{
	int a, b;
	double c;
}; // int형 2개 * 4Byte, double형 1개 * 8Byte, 총 16Byte 이상

void sub(struct test si) // 구조체 그대로 매개변수 사용 시 16Byte 이상의 메모리가 소요
{
	........
}

int main()
{
	struct test im;  // 구조체 선언
	.....
	.....
	sub(im); // 선언한 구조체를 그대로 사용
	.....
}

 

_example_최적화 후

struct text
{
	int a, b;
	double c;
}; 

void sub(struct test* si) // 구조체가 아닌 구조체포인터를 매개변수로 사용 시 단 4Byte 메모리가 소요
{
	........
}

int main()
{
	struct test im;  // 구조체 선언
	.....
	.....
	sub(&im); // 구조체 주소를 사용
	.....
}

 

2. 4Btye 이상의 데이터는 포인터로 전달

_example_최적화 전

void sub(double m1, double 2m) // double형 2개 * 8Byte, 총 사용 메모리 16Byte
{
	.....
}

int main()
{
	double im, si;
    .....
    
    .....
    sub(im, si);
    .....
}

_example_최적화 후

void sub(double* m1, double* 2m) // double형 포인터 변수 2개 * 4Byte, 총 사용 메모리 8Byte
{
	.....
}

int main()
{
	double im, si;
    .....
    
    .....
    sub(&im, &si); // 인자값으로 주소값 전달
    .....
}

 

3. 여러 개의 매개변수를 구조체로 전달

_example_최적화 전

struct test
{
	int a, b;
    double c;
}

void sub(double o, double p, double q, double r, double s) // double형 8Byte * 5개, 총 40Byte 사용
{
	.....
}

int main()
{
	double a, b, c, d, e;
    struct test im;
    .....
    .....
    sub(a, b, c, d, e);
    .....
}

 

_example_최적화 후

struct test
{
    double a, b, c, d, e;
}

void sub(struct test* si) // 구조체 포인터 4Byte, 이전 대비 1/10 수준의 메모리 사용
{
	.....
}

int main()
{
	double a, b, c, d, e;
    struct test im;
    .....
    im.a = a;
    im.b = b;
    .
    .
    .....
    sub(&im); // 구조체 주소를 전달
    .....
}

 

연산의 최적화

1. 실수 연산을 최소화(정수의 연산으로)

_example_최적화 전

int main()
{
	double a = 5.0, b = 3.0, c;
    double d = 15.34, e = 3.0, f;
    d = a * b;
    
    f = d * e;
}

_example_최적화 후

int main()
{
	int p, q, r;
    double a = 5.0, b = 3.0, c;
    double d = 15.34, e = 3.0, f;
    
    p = a; // a를 p에 넣음으로 정수값을 가짐
    q = b;
    r = p * q; // 정수와 정수의 연산으로..
    
    p = d * 100; // 실수를 정수로 변환
    q = e * 100;
    f = (p * q) / 100; // 정수 연산 후 다시 실수로 변환
}

 

2. 변수 스코프 고려하기

- 전역 변수로 사용할지 지역변수로 사용할지 사용 용도에 따라서 신중히 결정

int main()
{
int i; // 루프 안에 사용할 변수는 루프 밖에서 선언하지 않기. 물론 밖에서 선언해야 할 필요성을 고려해야 함
while()
{
	int i; // 루프 내에서 사용할 시에는 루프 안에 선언
	i = 6;
}
}

 

3. 안정성 확보를 통한 최적화

1. const 활용

void sub(const double m1, double m2) // 변경이 일어나야 할지 말지를 계산하여  const로 선언
{
	m1 = 5.9;
    m2 = 4.7;
}

int main()
{
	double im, si;
    .....
    
    .....
    sub(im, si);
}

'프로그래밍 언어 공부 > C' 카테고리의 다른 글

문자 처리 라이브러리  (0) 2022.01.12
라이브러리(Library)  (0) 2022.01.12
디버깅(Dubugging)  (0) 2022.01.11
컴퓨터 언어 종류  (0) 2022.01.11
컴퓨터 언어 개요  (0) 2022.01.11