본문 바로가기

Develop/Java

Java 연산자 우선순위와 표현식 평가순서

728x90

과거에 김포프 선생님의 COMP1500을 수강하던 중
C#에서의 if문 평가(evaluation) 순서에 대해 공부한 적이 있습니다.

 

코딩을 오랫동안 한 사람은 이에 간과하고 자연스럽게 사용할 수 있지만

초심자 입장에서는 어떤 식이 먼저 평가되고 처리되지 않는지 명백하게 알아둬야 할 필요가 있습니다.

그럼 먼저 식의 평가 순서에 대해서 부터 알아보겠습니다.

 

평가 순서

if (1 + 1 == 2 || 3 + 2 == 5 && 1 + 2 == 2) {
	// 코드 생략
}

먼저 이 코드 Snippet을 보게 되면, 우선순위는 `&&`가 `|| `보다 높습니다.

하지만 평가는 1 + 1 == 2 부분이 실행되며 1 + 1 == 2가 참이기 때문에 뒤의 3 + 2 == 5 1 + 2 == 2

코드 자체가 실행이 되지 않습니다.

 

사실 이러한 과정에는 어떤 식으로 컴파일러가 처리를 할지에 대한 규약이 존재합니다.

 

여러 가지 표현식이 존재하고 거기에 다양한 연산자로 연결이 돼 있을 때

`|| `와 `&&`는 코드의 한 줄의 종료를 의미하는 사용하는 사용할 때 ;(세미콜론)와 같이

동일한 시퀀스 포인트이기 때문에 해당 코드 라인만을 평가하게 되며

 

불필요한 연산을 하지 않음으로 실행 속도를 높이는 기능인 Short Circuit이 사용되어

1 + 1 == 2 이후의 식은 실행되지 않는 것입니다.

 

쇼트 서킷 Short Circuit

이러한 쇼트서킷이라는 기능이 있기 때문에 프로그래머는 이를 적절히 활용해서 성능을 높이는 작업을 해줘야 합니다.

예를 들면 True, False값이 간단하게 나오는 상황을 앞 쪽에다가 적용하면

이미 앞에서 boolean 값이 결정되기 때문에 빠르게 처리할 수 있는 것입니다.

 

조건문의 첫 표현식의 평가가 True일 경우 발생되는 단축 평가는

뒤 표현식들의 True, False값을 판단하지 않기 때

문에 단위 테스트를 할 때 위험할 수 있습니다.

테스트를 할 때 모든 조건을 테스트를 해줘야 하는데 앞에서 True, False를 결정해버려서 뒤에 조건을 정확하게 테스트할 수 없을 수도 있기 때문입니다.

 

if (1 + 0 == 2 || 3 + 1 == 5 && 1 + 2 == 3) {
	// 코드 생략
}

만약 코드가 위와 같이 변경된다면

 

첫 번째 표현식인 1 + 0 == 2 은 False로 평가되고 뒤의 표현식들을 평가하게 되며

두 번째 표현식인 3 + 1 == 5 은 False로 평가되고 마지막 표현식을 실행하게 됩니다.

마지막 표현식인 1 + 2 == 3 은 True로 평가되며 `&&` 연산자 즉 AND 연산이 발생하여

앞의 표현식과 비교를 통해 False && True 를 통해 False의 결과가 발생하고

다시 한번 앞의 표현식 `||` 연산자 OR이 발생하여 False || False의 결과로써

최종 조건문의 결과는 False가 발생하게 되는 것입니다.

 

 

사실 이러한 쇼트서킷을 이용하여 성능 상의 이점을 가져올 수 있는데

표현식의 평가 순서가 빠른 식을 평가의 앞쪽에 배치하는 것으로 성능상의 이점을 가져올 수 있습니다.

반대로 오히려 연산의 순서를 정하기 때문에 병렬 처리를 막아 성능 저하를 시킬 수도 있습니다.

 

if ( a() + b() * c() - d() ) {
	// 코드 생략
}

 

위의 코드 같은 경우에 연산 순서는 b() * c() 를 먼저 하겠지만 a() 메서드를 먼저 실행할지 b(), c(), d() 메소드를 먼저 실행할지는 컴파일러가 정하기 때문에 그런 것들을 잘 고려해서 조건문을 처리할 필요가 있습니다.

 

결과적으로 조건문에서 퍼포먼스를 높이려면 괄호를 적절히 사용해서

프로그래머가 원하는 연산 순서로 진행되게 하면서 간단한 조건을 먼저 연산할 수 있게 두는 방법을 사용하면 됩니다.

 

연산자 우선 순위 Operator

수학에서 곱셉과 나눗셈을 덧셈보다 먼저 연산하듯이 프로그래밍 언어에서 사용하는 연산자 사이에서도 우선순위가 있습니다. 연산자의 결합 순서는 수학과 마찬가지로 대부분 왼쪽에서 오른쪽이다. 몇몇 소수의 연산자만이 오른쪽에서 왼쪽으로 결합합니다.

 

위의 표는 언어에서 사용하는 연산자와 연산자의 우선순위를 정리한 것입니다.

굳이 위의 표를 모두 외울 필요는 없고 연산자에도 우선순위가 있다는 것을 인지만 하고 있으면 좋을 것 같습니다. 

 

참고

https://jeong-pro.tistory.com/138