HOWTO · Java
자바 인라인 함수
Java에는 소스 수준의 `inline` 선언이 없습니다. JVM이 런타임에 메서드를 인라이닝할 수 있는 방식과 메서드 호출 및 동등한 문장을 비교하는 예제를 설명합니다.
이 페이지의 내용
Java에는 소스 수준에서 inline 함수를 선언하는 문법이 없습니다. Java 인라인 함수를 검색하는 개발자는 보통 메서드 인라이닝을 뜻합니다. 이는 JVM이 메서드 호출을 해당 메서드의 명령어로 대체할 수 있는 런타임 최적화입니다. 개발자는 일반적인 Java 메서드를 작성하고, 프로그램 실행 중 호출을 인라이닝할지는 JVM이 결정합니다.
Java에서 메서드 인라이닝이란?
일반적으로 메서드를 호출하면 실행 흐름이 해당 메서드로 이동한 뒤 결과를 반환합니다. 인라이닝은 컴파일된 기계어에서 호출 지점에 메서드의 명령어를 배치해 그 호출을 없앨 수 있습니다. 이는 JVM 최적화이며 Java 소스 코드를 바꾸는 작업도, 코드를 직접 복사해 수행하는 작업도 아닙니다. Java 컴파일러는 여전히 소스를 클래스 파일로 컴파일하고, 런타임 실행과 최적화는 JVM이 담당합니다.
인라이닝이 모든 메서드를 어디서나 확장한다는 뜻은 아닙니다. 런타임은 프로그램의 동작을 보존해야 하며, 인라이닝이 적절하지 않으면 호출을 그대로 둘 수 있습니다. 메서드는 명확하게 작성하고, 이 구현상의 선택은 JVM에 맡기세요.
HotSpot JVM은 메서드 인라이닝을 어떻게 수행하나요?
HotSpot의 JIT(Just-In-Time) 컴파일러는 런타임 최적화의 일부로 조건에 맞는 메서드 호출을 인라이닝할 수 있습니다. 이 결정은 코드와 런타임 조건에 따라 달라지며 Java 언어가 보장하는 동작이 아닙니다. 따라서 모든 JVM에서 인라이닝이 항상 활성화되어 있다고 설명하거나, 이 예제를 실행하는 데 특정 구현 전용 플래그가 필요하다고 안내하지 마세요. 아래 예제는 서로 동등한 계산을 보여 주지만, HotSpot이 내부적으로 무엇을 컴파일하는지 제어하거나 드러내지는 않습니다.
메서드 호출과 동등한 문장을 비교하는 Java 예제 만들기
첫 번째 계산은 addBonus를 호출한 다음 score를 호출합니다. 두 번째 계산은 같은 산술 연산을 직접 수행합니다. 두 계산은 같은 값에서 시작하므로 JVM이 실제로 어느 호출이든 인라이닝했다고 주장하지 않고도 결과를 비교할 수 있습니다.
다음 예제를 실행해 보세요. 코드와 출력 블록의 레이블은 바이트 단위 보존을 위해 영어로 표시됩니다.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
public class Main {
static int addBonus(int score) {
return score + 2;
}
static int score(int value) {
return value * 3;
}
public static void main(String[] args) {
int byMethodCalls = score(addBonus(4));
int value = 4;
int byStatements = (value + 2) * 3;
System.out.println("Method calls: " + byMethodCalls);
System.out.println("Direct statements: " + byStatements);
}
}
Method calls: 18
Direct statements: 18
예제 컴파일 및 실행하기
소스를 빈 작업 디렉터리에 Main.java라는 이름으로 저장하세요. 해당 디렉터리에서 PATH에 JDK가 등록되어 있는지 확인한 뒤 컴파일하고 실행합니다.
해당 디렉터리에서 javac Main.java를 실행한 다음 java Main을 실행하세요. 이 명령은 앞서 나온 클래스 이름과 파일 이름을 사용하며 JVM 튜닝 옵션은 필요하지 않습니다. 제공된 이 예제의 실행은 성공적으로 끝났고, 위에 표시된 출력을 냈습니다.
결과가 보여 주는 것과 보여 주지 않는 것
프로그램을 실행하면 출력된 두 값을 비교하세요. 메서드 호출과 직접 쓴 식이 같은 산술 연산을 수행하므로 두 값은 같아야 합니다. 이를 통해 이 간단한 예제에서 결과가 서로 동등함을 확인할 수 있습니다. 하지만 이 결과만으로 JVM이 두 메서드 중 하나를 인라이닝했는지는 알 수 없습니다. 값이 같다는 사실은 어느 방식이 더 빠른지도 알려 주지 않습니다. 성능을 측정하려면 별도의 통제된 벤치마크가 필요합니다. 요약하면, 읽기 쉬운 소스 코드를 위해 일반적인 Java 메서드를 사용하고, 인라이닝은 직접 선언하는 기능이나 이 출력만으로 성능을 추론할 수 있는 결과가 아니라 런타임에 적용될 수 있는 최적화로 이해하세요.