포스트

Short-Circuit Evaluation

Short-Circuit Evaluation

Short-Circuit Evaluation


단락 방식

참고 - 위키피디아, 참고 - 제로니모님의 글

대부분의 프로그래밍 언어에서는, 불 연산에 Short-Circuit Evaluation 이 적용된다.

그림

위 그림처럼,
순서대로 연산하는 도중 이미 결과가 결정되는 경우,
굳이 남은 피연산자들까지 계산할 필요가 없기 때문에, 결과가 결정된 시점에서 계산을 마친다.

1
2
SomeObject a = null;
if (a != null && a.SomeFunc())

C# 에서 && 은 Short-Circuit Evaluation 이 적용되기 때문에,
위 코드에서는 a != null 에서 계산이 끝나고, a.SomeFunc() 가 실행되지 않아 런타임 에러가 발생하지 않는다.
이런식으로 활용할 수 있다.

만약 Short-Circuit Evaluation 이 적용되지 않았다면,
위 코드에서 anull 인채로 a.SomeFunc() 가 실행되어 NullReferenceException 이 발생했을 것이다.

1
2
3
4
5
6
7
8
9
// 1: 최소 1ms
if (takes1ms() || takes1s())
// 2: 최소 1s
if (takes1s() || takes1ms())

// a: 최소 O(1)
if (boolVariable || take1s())
// b: 최소 1s
if (takes1s() || boolVariable)

또, 만약 함수의 반환 값을 피연산자로 사용하는 경우,
상대적으로 비용이 높은 함수를 뒷쪽에 배치하여 시간 복잡도를 줄일 수도 있다.

1
2
if (false & SomeFunc())
if (true | SomeFunc())

반면, 결과와 상관없이 피연산자로 존재하는 모든 함수들을 실행시키고 싶은 경우가 있을 수 있다.
(예시가 딱 떠오르지는 않지만)

이 경우, C# 에서는 & 이나 | 를 사용할 수 있다.
&| 는 비트 연산자로 쓰이기도 하지만, 불 연산 식에 사용될 경우, 불 논리 연산자로써 사용된다.

& 이나 | 를 불 논리 연산자로써 사용하면, 결과와 상관없이 모든 피연산자들을 계산한다.
때문에 위 두 줄의 코드는, 첫 번째 피연산자에서 이미 결과가 결정되어버리지만, 계산을 끝내지 않고 SomeFunc() 함수를 실행시킨다.

이때, 이런 &|&&|| 에 구분지어,
Eager Operators (&, |) 와 Short-Circuit Operators (&&, ||) 로 부를 수 있다.


C# 튜플 비교 시, Short-Circuit Evaluation 이 적용된다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.