Series/내가 해본

enum 을 조회하는 방법

Hyunec 2021. 1. 13. 14:21

회사의 enum 조회 코드를 보다가 불현듯 이펙티브 자바와 블로그에서 본 개선 방법이 생각나서 실험을 해봤습니다.

  • Spring boot 2.x.x, Java 11
  • 테스트 코드 Repository Link
enum 조회 시 Stream, Array, Map의 성능 차이는 얼마나 될까?
@Getter
@AllArgsConstructor
public enum CategoryColor {

	YELLOW(0, "#FEDE00"),
	BLUE(1, "#85C4E7"),
	ORANGE(2, "#F3AC13"),
	...
	;

	private final int order;
	private final String code;

	public static final Map<Integer, CategoryColor> categoryColorMap = new HashMap<>();

	static {
		for (final CategoryColor color : CategoryColor.values()) {
			categoryColorMap.put(color.getOrder(), color);
		}
	}

	public static String getColorByHashMap(final int order) {
		return categoryColorMap.get(order).code;
	}

	public static String getColorByArray(final int order) {
		return CategoryColor.values()[order].code;
	}

	public static String getColorByStream(final int order) {
		return Arrays.stream(CategoryColor.values())
				.filter(categoryColor -> categoryColor.order == order)
				.findAny()
				.map(CategoryColor::getCode)
				.orElse(CategoryColor.YELLOW.code);
	}
}
	@Test
	void byStream() {
		stopWatch.start("byStream");
		IntStream.range(0, 100000000).forEach(order -> CategoryColor.getColorByStream(1));
		stopWatch.stop();
	}

	@Test
	void byArray() {
		stopWatch.start("byArray");
		IntStream.range(0, 100000000).forEach(order -> CategoryColor.getColorByArray(1));
		stopWatch.stop();
	}

	@Test
	void byHashMap() {
		stopWatch.start("byHashMap");
		IntStream.range(0, 100000000).forEach(order -> CategoryColor.getColorByHashMap(1));
		stopWatch.stop();
	}

1억건 대비 HashMap 과 Array 조회의 큰 차이가 없음

기존의 Array 형태 대비 HashMap 이 빠른 것은 맞지만 HashMap (or EnumMap)을 이용한 조회는 코드량이 늘어나고, 기존 코드들과의 일관성을 해쳐 다른 동료들이 익숙하지 않은 스타일이기에 기존의 방식을 유지하기로 했습니다.
리팩토링을 위한 좋은 방법은 앞으로도 나오겠지만, 기대하는 성능 대비 소모 값을 검증해봐야 된다는 것을 다시 한번 느꼈습니다.

Stream 도 어서 저만큼 빨라지기를!