최적화란?
- 정보공학에서 시스템을 수정하여 어떠한 면의 작업을 더 효과적으로, 또는 자원을 덜 사용하도록 만드는 작업
- 컴퓨터 프로그램은 더 빠르게 실행되거나 기억 장치 또는 자원을 덜 차지하게 하여 운영하도록 개선
- 유지보수의 편의성을 고려한 코드 개선
- 안정성 확보를 위한 최적화
최적화 기법
- 성능 체크 : 최적화 대상 선정
- 코드 분석 : 최적화 향상
- 병목지점 찾기 (소요시간)
- 구조체 복사 시 대입연산자 대신 라이브러리 함수를 이용
- 구조체 전달은 포인터를 이용
- 함수의 매개변수를 축소 (4개 이하: 레지스터 이용, 4개 이상: 스택 이용)
- 4Byte 이상 전달 시 포인터를 이용
- 4개 이상인 경우 인자를 구조체로 선언하고 구조체 포인터를 매개변수로 전달
- const를 적절히 활용 (안정성 확보 차원)
- 2의 n 제곱을 곱하는 연산은 쉬프트 연산 수행
- 실수연산을 축소
- 소수점 이하 2자리까지만 필요한 연산 -> 실수의 연산에서 100을 곱한 후 연산을 해 100으로 나눔
- 지역변수를 최대한 활용
- 전역변수 사용을 최소화
매개변수 최적화
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 |