2011-10-13 2 views
4

내 코드의 성능에 대한 질문이 있습니다. 의가 나는 점 C에서 구조체 있다고 가정 해 봅시다 :ANSI C# VS 함수 정의

typedef struct _CPoint 
{ 
    float x, y; 
} CPoint; 

내가 구조체를 사용하는 함수를.

float distance(CPoint p1, CPoint p2) 
{ 
    return sqrt(pow((p2.x-p1.x),2)+pow((p2.y-p1.y),2)); 
} 
가 정의 #이 기능을 대체하는 현명한 생각 될 경우 궁금

,

#define distance(p1, p2)(sqrt(pow((p2.x-p1.x),2)+pow((p2.y-p1.y),2))); 

나는 어떤 기능을 오버 헤드가 없기 때문에 더 빨리 될 것이라고 생각, 내가 ' 성능 향상을 위해 프로그램의 다른 모든 기능에 대해이 접근 방식을 사용해야하는지 궁금합니다. 그래서 내 질문은 :

내 코드의 성능을 향상 시키려면 #define으로 모든 기능을 대체해야합니까?

+0

밑줄을 사용하는 대신 꼬리말을 사용하십시오. 대부분의 밑줄 문자는 ISO C 표준을 위반하며 대문자가 뒤에 오는 밑줄 문자는 새로운 C 언어 키워드가 사용하는 것과 같이 특히 나쁩니다 ('_Bool', _Complex','_Generic','_Atomic', ...) – Christoph

답변

8

아니요. 인식 된 성능 차이에 따라 매크로와 함수를 절대로 결정해서는 안됩니다. 매크로에 대한 함수의 장점을 토대로이를 평가해야합니다. 일반적으로 기능을 선택하십시오.

매크로에는 당신을 물릴 수있는 숨겨진 단점이 많이 있습니다. 예를 들어, 매크로로의 번역이 잘못되었습니다 (또는 적어도 원래 함수로 유지되는 의미론이 아님). 매크로 distance에 대한 인수는 각각 2 번 평가됩니다. 다음과 같은 호출을했다고 상상해보십시오.

매크로 버전에서는 각 인수가 두 번 평가되므로 실제로는 4 개의 함수 호출이 발생합니다. distance이 함수로 남아 있다면 3 개의 함수 호출 (거리 및 각 인수) 만 발생합니다. 참고 : 위의 계산에는 sqrtpow의 영향을 무시하고 있습니다. 두 버전이 동일하기 때문입니다. 그들은 또한이 발생,

  • 정상적인 기능 당신의 distance
  • 위의 인라인 함수와 같은
  • 처리기 매크로

기능 형 안전의 어떤 종류를 보장하는 동안 :

3

은 세 가지가 있습니다 각 함수 호출시 스택 프레임을 사용해야한다는 사실로 인해 성능이 저하됩니다. 인라인 함수의 코드가 콜 사이트에서 복사되어 페널티가 지불되지 않지만 코드 크기가 증가합니다. 매크로는 유형 안전성을 제공하지 않으며 텍스트 대체도 포함합니다.

세 가지 중에서 선택하면 일반적으로 인라인 함수를 사용합니다. 매크로가 매우 짧고이 형식에서 매우 유용 할 때만 (예 : 리눅스 커널의 hlist_for_each)

3

매크로가 아닌 inline 함수를 사용하는 것이 좋습니다. 추악함없이 매크로의 가능한 성능 이점을 모두 제공합니다. (매크로에는 함수를 대체 할 수있는 함수가 많이 있는데, 특히 매크로 arg는 사용 될 때마다 평가되고 함수 arg는 "호출"전에 한 번 평가됩니다.)

inline float distance(CPoint p1, CPoint p2) 
{ 
    float dx = p2.x - p1.x; 
    float dy = p2.y - p1.y; 
    return sqrt(dx*dx + dy*dy); 
} 

(어떤 컴파일러는 pow에 전화를 멀리 최적화하기 위해 시도 할 수 있습니다. 두 가지가 동일하고, 곱셈이 효율적으로 가능성이 높습니다. 나는 또한 dx * dxpow(dx, 2)를 대체합니다 ...하지만 그들이 대체 무엇인지 추측 그것과 함께.)

1

만약에 성숙한 컴파일러를 사용한다면, 최적화가 필요하다면 프로파 바이트가 어셈블리 레벨에서 이것을 할 것입니다.

gcc의 경우 -O3 또는 ("작은"기능의 경우) -O2 옵션조차도이 작업을 수행합니다.

자세한 내용은 http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html의 "-finline *"옵션을 참조하십시오.

3

제러드가 옳다.이 특정 경우, pow 호출과 sqrt 호출에 소비되는 사이클은 distance 호출에 소비 된 사이클보다 2 배 더 큰 범위에있다.

때때로 사람들은 작은 코드가 작은 시간과 같다고 가정합니다. 별로.