• 변수별 특성
• 재귀함수 최적화
#include <stdio.h>
#if TCASE==1 //재귀
int fact(int n) {
if((n==1) || (n==0)) return 1;
else return n * fact(n-1);
}
#elif TCASE==2 //goto로 하는 루프
int fact(int n) {
int i=1, rst=1;
if(n==0) return 1;
loop:
if(i<=n) rst *= i++;
else return rst;
goto loop;
}
#elif TCASE==3 // for문
int fact(int n) {
int i, rst=1;
if(n==0) return 1;
for(i=1; i<=n; i++) rst *= i;
return rst;
}
#endif
int main(void)
{
fact(5);
return 0;
}
재귀,goto,반복문으로 팩토리얼 연산을 하는 소스코드를 컴파일한 후 디스어셈블해서 비교
- 컴파일, 디스어셈블리 명령어
gcc recursiveFunc.c -g -DTCASE=3
objdump -d -S a.out > r3
재귀 함수는 반복적인 처리를 짧은 코드와 효과적인 처리로 편의를 제공하지만, 함수의 반복적인 호출 은 비용이 많이 들며 이전 계산 결과가 필요한 재귀 함수는 성능이 낮은 걸 알 수 있다
• 함수 인자 최적화
• 비용이 낮은 연산자 선택
% 연산보다는 & 연산을, / 연산보다는 >> 연산을 하는게 좋다
#include <stdio.h>
int main(void)
{
int d1, d2, d3, d4;
d1 = 51; d2 = 51;
d1 %= 8;
d2 &= 7;
printf("d1:%d, d2:%d\n", d1, d2);
d3 = 31; d4 = 31;
d3 /= 4;
d4 >>= 2;
printf("d3:%d, d4:%d\n", d3, d4);
return 0;
}
• short circuit 원리
&& 조건은 앞이 거짓이면 뒤 실행 X
|| 조건은 앞이 참이면 뒤 실행 X
&& - 논리곱은 거짓일 확률이 높은 문장을 앞쪽에 둠
|| - 논리합은 참일 확률이 높은 문장을 앞쪽에 둠
• 연관된 표현의 묶음 처리
나눗셈 연산을 묶는건 묶음 처리로 적절하지만
스위치 문을 비트연산으로 변환한 경우는 가독성이 크게 떨어져버린다
적절하게 묶음 처리하자
• 프로파일링 활용 최적화
time 유틸리티
clock() 함수
- gprof 유틸리티 프로파일링 예제
#include <stdio.h>
#include <stdlib.h>
int prime(int num);
int main(void)
{
int i;
int colcnt = 0;
for(i=2; i<=50000; i++) {
if(prime(i)) {
colcnt++;
if(colcnt%9 == 0) {
printf("%05d\n", i);
colcnt = 0;
} else {
printf("%05d ", i);
}
}
}
putchar('\n');
return 0;
}
int prime(int num)
{
int i;
for(i=2; i<num; i++) {
if(num%i == 0) return;
}
return 1;
}
cc -pg -o profile profileTest.c
./profile
gprof -b ./profile
'대외활동 > 시스템프로그래밍' 카테고리의 다른 글
메서드 오버로딩 & 디폴트 매개변수 & static & 프렌드 & 연산자 오버로딩 (0) | 2024.07.26 |
---|---|
C++ 객체지향 프로그래밍 (0) | 2024.07.25 |
보이드 포인터를 이용한 제네릭 프로그래밍 (1) | 2024.07.23 |
부트로더 (0) | 2024.07.23 |
함수 포인터, 구조체 포인터 예제 (0) | 2024.07.23 |