비트 필드 대신 EnumSet을 사용하라

수박참외메론·2023년 1월 29일
1

비트 필드란

비트 필드 (bit masking 이라고도 함) 은 보통 하나의 int 형 변수에 2의 제곱마다 특정한 의미를 가지게 하여 그 의미들을 중첩해서 나타내도록 하는 기법 중 하나다. 이는 메모리에 값을 저장할 때 bit 단위로 저장하는 컴퓨터의 특징 때문에 메모리 효율적이고, 비교적 빠르게 저장할 수 있다는 장점을 가지고 있다.

예전에야 메모리 한 비트가 중요해 이런식으로 특정 설정값을 저장해 사용했다고 하지만, 요즘에는 여러 이유 때문에 메모리 공간이 넉넉한 환경에서는 보통 사용되지 않는다.

public class Text {
	public static final int STYLE_BOLD			 = 1 << 0;
    public static final int STYLE_ITALIC		 = 1 << 1;
    public static final int STYLE_UNDERLINE		 = 1 << 2;
    public static final int STYLE_STRIKETHROUGH	 = 1 << 3;
    
    public void applyStyles(int styles) { ... }
}

위에 코드에서 알 수 있듯이 bold, italic, underline, strikethrough 처럼 컴퓨터에서 나타나는 text 에서 중첩될 수 있는 설정값들을 어떻게 설정할 것인가 생각하면 boolean 형 4개를 하나의 클래스에서 설정하는 방법을 생각할 수 있겠지만,

위에처럼 더 효율적으로 1111(2진법) 으로 나타내 15라는 정수값 하나로 해당 글자의 스타일을 저장할 수 있다.

text.applyStyles(STYLE_BOLD | STYLE_ITALIC);

bit field 를 이용하여 text 의 스타일을 지정하는 방법은 or 비트 연산자를 이용하여 값들을 중첩시킬 수 있다.

하지만 이 비트필드는 정수 열거 상수의 단점을 그대로 지니며, 아래와 같은 추가적인 문제도 안고 간다.

  • 가독성이 매우 떨어진다.
    디버깅을 할 때 style = 15라는 정수값이 도대체 무슨 값인지 저 로직을 다 파악하지 않는 이상 알 방법이 없다.
  • 최대 몇 비트가 필요한지 API 작성 시 미리 예측하여 int 형으로 할지 long 형으로 할지 판단해야한다.

EnumSet

java.util 패키지의 Enumset 클래스는 열거타입 상수의 값으로 구성된 집합을 효과적으로 표현해준다. Set 인터페이스를 완벽히 구현하며, 타입안전하고, 다른 Set 구현체와도 함께 사용할 수 있다.

또한 내부적으로 비트 벡터로 구현되어있어, 원소가 64개 이하라면 long 변수 하나로 표현되는 비트필드와 비견되는 성능을 보여준다.

쉽게 말해서 가독성 문제를 해결해주고, 원소를 얼마나 가지느냐에 따라 bit field 를 알아서 설정해주는 듯한 기능을 하는 Set 구현체이다.

public class Text {
	public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }
    
    public void applyStyles(Set<Style> styles) {...}
}
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));
profile
하루하루는 성실하게 인생전체는 되는대로

0개의 댓글