2015년 12월 27일 일요일

javascript: Short Circuit Evaluation ; 단락 회로 평가

Short Circuit Evaluation, 한국말로 하자면 '단락 회로 평가'입니다. 이거 뭐임? 하는 분들도 계시겠지만, 많은 분들이 알고 있는 내용이기도 하며, javascript 뿐만 아니라 수많은 고급 프로그래밍 언어의 특징 중에 하나이기도 합니다.

원래 초기 컴퓨팅 파워가 엄청 비싼 시절(진공관 컴퓨터 밖에 없었을때요..)에 전력사용량 절감과 한 싸이클이라도 연산 속도를 빠르게 하기 위해 생겨나게 된 개념입니다.

거두절미 하고 아래 코드를 보시죠.
( 좋은 코드는 아닙니다만, 설명을 위한것이니 그냥 그러려니.. 해주세요. )

var code = 1;
var value = 0;
if( code++ || value++ ) {
    console.log( "Code" );
} else {
    console.log( "Default" );
}
console.log( "Code : " + code );
console.log( "Value : " + value );

논리적으로만 보자면,
Code
Code : 2
Value : 1
이 나와야겠죠?

하지만 실제로는
Code
Code : 2
Value : 0
이 나옵니다.

비밀은 '||' 연산자에 있습니다. 아주 흔히 사용되는 이 연잔사는 피연산자가 두개인 이항연산자 입니다. 즉, 연산자를 중심으로 좌변과 우변에 식이 올 수 있는데요, 'or'의 특성상 좌변의 평가결과가 참이면 우변은 참이던 거짓이던 전체결과는 무조건 참이므로 우변에 대한 평가를 생략합니다. '&&'의 경우 'and'의 특성상 좌변이 거짓이면 우변은 평가를 생략하게 되죠. 이 평가기법이 Short Circuit Evaluation, 또는 단락 회로 평가라고 하는 특징입니다.

이 단락회로평가가 평소에는 그저 조금더 빠른 연산을 보장하지만, javascript에서는 특히나 아래와 같은 활용이 가능해 집니다. ( 아래 코드는 sourceString이 undefined이거나 null인 경우에만 활용이 가능하며, sourceString에 숫자 '0'이 들어오지 않는다는 보장이 있을 경우에만 사용해야 합니다. )

function wrap( sourceString ) {
    var normalizedString = sourceString;
    normalizedString || ( normalizedString = "" );
    return "<my-tag>" + normalizedString + "</my-tag>;
}

위의 wrap함수는 "<my-tag>undefined</my-tag>"나 "<my-tag>null</my-tag>"와 같은 이상한 출력을 방지하기 위한 코드입니다.

또는 아래와 같은 함수가 있을수도 있겠죠?

var lightCost = false;
var heavyCost = false;
if( lightCost = lightCostOperation() && heavyCost = heavyCostOperation() ) {
   ....
}

위의 코드는 lightCost가 false인 경우 heavyCostOperation을 수행하지 않을 수 있습니다. 일반적으로 if-then-else 구문에서 각각의 조건블럭이 3개를 초과하면 가독성이 떨어진다고 볼 수 있는데, 이 단락 회로 평가를 활용하면 조건블럭을 줄일 수도 있고, 비용이 높은 연산을 자연스럽게 스킵하는 효과도 거둘 수 있습니다. 이 것은 대부분의 고급언어에서 많이 활용되고 있는 기법입니다.

이렇게 단락회로평가를 하지 않도록 하고 싶으시다면, '&&'나 '||' 대신에 '&', '|'를 사용하시면 됩니다.( 사실 '&', '|'는 Javascript의 Bitwise연산자 이기 때문에 피연산자가 정수로 변환될 수 있는 타입이라면 의도하지 않는 연산이 수행될 수도 있습니다. )

프로그래밍을 많이 해 보신 분들에게 단락 회로 평가는 그리 신기하거나 특이한 기능은 아닐 수도 있습니다. 하지만 이걸 모르면 심각한 버그를 키워낼 수 있는 만큼 기본 중의 기본이라고 할 수 있겠습니다.

단락회로 평가에 대한 소개는 여기서 마치도록 하겠습니다.

댓글 없음:

댓글 쓰기