2010-05-17 3 views
7

몇 주 전에 C#으로 작업하기 시작했습니다. 알고리즘의 다른 케이스를 처리하기 위해 "비트 세트"플래그를 만들어야하는 상황에 처했습니다.C#에서 일반 int sum 대신 비트 연산자를 사용하면 성능이 크게 향상됩니까?

enum RelativePositioning 
    { 
     LEFT = 0, 
     RIGHT = 1, 
     BOTTOM = 2, 
     TOP = 3, 
     FRONT = 4, 
     BACK = 5 
    } 

    pos = ((eye.X < minCorner.X ? 1 : 0) << (int) RelativePositioning.LEFT) 
     + ((eye.X > maxCorner.X ? 1 : 0) << (int) RelativePositioning.RIGHT) 
     + ((eye.Y < minCorner.Y ? 1 : 0) << (int) RelativePositioning.BOTTOM) 
     + ((eye.Y > maxCorner.Y ? 1 : 0) << (int) RelativePositioning.TOP) 
     + ((eye.Z < minCorner.Z ? 1 : 0) << (int) RelativePositioning.FRONT) 
     + ((eye.Z > maxCorner.Z ? 1 : 0) << (int) RelativePositioning.BACK); 

또는 : 나는 이렇게 두 가지 옵션이 ((eye.X > maxCorner.X) << 1)

enum RelativePositioning 
    { 
     LEFT = 1, 
     RIGHT = 2, 
     BOTTOM = 4, 
     TOP = 8, 
     FRONT = 16, 
     BACK = 32 
    } 

    if (eye.X < minCorner.X) { pos += (int) RelativePositioning.LEFT; } 
    if (eye.X > maxCorner.X) { pos += (int) RelativePositioning.RIGHT; } 
    if (eye.Y < minCorner.Y) { pos += (int) RelativePositioning.BOTTOM; } 
    if (eye.Y > maxCorner.Y) { pos += (int) RelativePositioning.TOP; } 
    if (eye.Z > maxCorner.Z) { pos += (int) RelativePositioning.FRONT; } 
    if (eye.Z < minCorner.Z) { pos += (int) RelativePositioning.BACK; } 

내가 사용했을 수있는 일을하지만, C#을 부울에서 암시 적 캐스팅이 int로 허용하지 않고 삼항 연산자가 충분히 유사했다. 내 질문은 지금 : 두 번째 이상의 첫 번째 버전을 사용하여 성능 향상이 있습니까?

번째 예에서 표준 if 목록과 거의 동일한 IL을 생성하면
마소

+8

벤치 마크는 그런 일을 보일 것이다 그런 식으로 최적화 –

+0

미치 밀 (Mitch Wheat)과 동의하십시오. 또한 프로파일 러에서 병목 현상을 입증 할 수 없다면 성능보다 가독성을 선호하십시오. – OregonGhost

+4

"시간의 약 97 %를 차지하는 작은 효율성을 잊어 버려야합니다. 즉각적인 최적화는 모든 악의 뿌리입니다."Donald Knuth – Cagdas

답변

5

인라인 if 연산자 (?, :)을 감사합니다. 여기서 볼 수있는 유일한 차이점은 프로세서가 수행 할 특정 작업이며 ADDSHL보다 빠릅니다.
어쨌든 결과를 추가 할 예정이므로 두 번째 예를 선택하십시오 (더하기 쉽게 읽을 수 있습니다).

편집
난 그냥 두 예제의 IL을 확인, 그리고 내가 위에서 말한에 간다.
첫 번째 예제는 훨씬 적은 IL (34 줄 이하)을 생성하므로 성능 테스트를 실행하여 실제로 속도가 더 빠른지를 결정해야합니다.

+0

+1에 대한 편집. –

0

현저하게 빠름? 아니. 약간 더 빠릅니까? 조금.

8

열거 형에 대해서는 Flags attribute을 사용해야합니다. 당신이 좋아하는 그런 일을 할 수있는이 함께

[Flags] 
public enum RelativePositionings 
{ 
    None = 0, 
    Left = 1, 
    Right = 2, 
    Bottom = 4, 
    Top = 8, 
    Front = 16, 
    Back = 32 
} 

:

var position = RelativePositionings.Left | RelativePositionings.Front; 

에 의해 각 상태를 확인 : 마이크로를 수행하기 전에

if(position.HasFlag(RelativePositioning.Left)) 
{ 
    //To do: if left bit is set? 
} 
관련 문제