조기 토론은 모든 사악한 근본 강의 삽입
즉, 불필요한 효율성을 피하기 위해 얻은 습관이 있으며 경우에 따라 코드를 더 간단하고 정확하게 만들 수 있습니다.
이것은 일반적인 원칙에 대한 논의가 아니라 불필요한 비효율적 인 코드 도입을 피하기 위해 알아야 할 사항입니다.
이것은 아마도 위의 긴 토론에 병합되어야합니다. 내부 루프가 계산을 반복하는 루프 내부의 루프가 느리다는 것은 매우 상식입니다. 예를 들면 다음과 같습니다.
for (i = 0; i < strlen(str); i++) {
...
}
루프가 반복 될 때마다 길이가 다시 계산되기 때문에 문자열이 실제로 길면 끔찍한 시간이 걸립니다. 참고 GCC가 있기 때문에 실제로이 사건을 최적화 strlen()
순수 함수로 표시됩니다.
백만개의 32 비트 정수를 정렬 할 때 버블 정렬은 잘못된 방법입니다 . 일반적으로 정렬은 O (n * log n) 시간 (또는 기수 정렬의 경우 더 나은)으로 수행 할 수 있으므로 데이터가 작을 것 같지 않다면 적어도 O (n) 인 알고리즘을 찾으십시오. * 로그 n).
마찬가지로 데이터베이스를 다룰 때 인덱스를 알고 있어야합니다. 당신이 경우 SELECT * FROM people WHERE age = 20
, 당신은 사람에 대한 인덱스 (나이)이없는, 그것이 O (N)가 필요합니다 순차 검색보다는 훨씬 빠른 O (로그 n)이 인덱스 스캔보다.
정수 산술 계층
C로 프로그래밍 할 때는 일부 산술 연산이 다른 연산보다 비싸다는 것을 명심하십시오. 정수의 경우 계층 구조는 다음과 같습니다 (최소한 비싸지 않음).
부여, 컴파일러는 같은 일반적으로 최적화 일 것이다 n / 2
에 n >> 1
자동으로 주류 컴퓨터를 대상으로하는 경우,하지만 당신은 임베디드 장치를 대상으로하는 경우, 당신은 그 고급 스러움을 얻을 수 있습니다.
또한, % 2
및 & 1
다른 의미를 갖는다. 나눗셈과 계수는 일반적으로 0으로 반올림되지만 구현이 정의되었습니다. 좋은 ol ' >>
이며 &
항상 부정적인 무한대로 반올림합니다. 제 의견으로는 훨씬 더 의미가 있습니다. 예를 들어, 내 컴퓨터에서 :
printf("%d\n", -1 % 2); // -1 (maybe)
printf("%d\n", -1 & 1); // 1
따라서 말이되는 것을 사용하십시오. % 2
처음에 글을 쓸 때 사용하여 좋은 소년이라고 생각하지 마십시오 & 1
.
비싼 부동 소수점 연산
같은 부동 소수점 연산 않도록 무거운 pow()
및 log()
정수 처리 특히 정말 그들을 필요로하지 않는다 코드. 예를 들어 숫자를 읽으십시오.
int parseInt(const char *str)
{
const char *p;
int digits;
int number;
int position;
// Count the number of digits
for (p = str; isdigit(*p); p++)
{}
digits = p - str;
// Sum the digits, multiplying them by their respective power of 10.
number = 0;
position = digits - 1;
for (p = str; isdigit(*p); p++, position--)
number += (*p - '0') * pow(10, position);
return number;
}
이러한 사용 pow()
(및이 를 사용하는 데 필요한 int
<-> double
변환)은 비용이 많이들뿐만 아니라 정밀 손실의 기회를 만듭니다 (실수로 위의 코드에는 정밀도 문제가 없습니다). 이것이 수학적이지 않은 상황에서 이러한 유형의 함수가 사용되는 것을 볼 때 나는이기는 이유입니다.
또한, 각 반복마다 10을 곱한 아래의 "영리한"알고리즘이 실제로 위의 코드보다 어떻게 더 간결한 지 확인하십시오.
int parseInt(const char *str)
{
const char *p;
int number;
number = 0;
for (p = str; isdigit(*p); p++) {
number *= 10;
number += *p - '0';
}
return number;
}