Enum 찾기의 달인 (효율적으로 찾기, spring bean과 맵핑)

2021. 3. 21. 02:17 JAVA/Java

enum 이전 포스팅 : https://sjh836.tistory.com/134

1. 이놈(Enum...)을 효율적으로 찾는 방법

  • 장르, 카테고리, 각종 컨텐츠 타입 등 enum 의 활용은 무궁무진하다. enum 을 잘 선언했다면, enum 을 잘 찾는 것도 중요하다
  • 예를들어 DB에 enum name 이 아닌.. 무언가 코드값만 저장하고, 꺼내쓸 때 코드를 enum 으로 바꾸는 상황을 가정해보자.
    • 다른 예제로는 API 응답값 내 코드를 우리 서비스의 enum 으로 바꿔쳐야한다던지..
  • 아래에서는 enum 을 찾아내는 3가지 예제 코드들이다.@Getter @AllArgsConstructor public enum 
  @Getter
  @AllArgsConstructor
  public enum OperatingSystemType {
      WINDOW("100"),
      UBUNTU("101"),
      MAC("102");

      private String code;
  }

  // 1번
  public static OperatingSystemType getOs1ByCode(String code) {
      for (OperatingSystemType os : OperatingSystemType.values()) {
          if (os.getCode().equals(code)) {
              return os;
          }
      }
      return null;
  }

  // 2번
  public static OperatingSystemType getOs2ByCode(String code) {
      // 또는 switch
      if ("100".equals(code)) {
          return OperatingSystemType.WINDOW;
      } else if ("101".equals(code)) {
          return OperatingSystemType.UBUNTU;
      } else if ("102".equals(code)) {
          return OperatingSystemType.MAC;
      } else {
          return null;
      }
  }

  // 3번
  public static final Map<String, OperatingSystemType> map = new HashMap<>();
  static {
      for (OperatingSystemType os : OperatingSystemType.values()) {
          map.put(os.getCode(), os);
      }
  }
  public static OperatingSystemType getOs3ByCode(String code) {
      return map.get(code);
  }
  • enum 이 몇개 없어서 반복을 길게하여(천만번) 테스트해보면 결과는 다음과 같다.
    • 1번은 3번보다 6배 느리다. (150ms)
    • 2번은 3번보다 2배 느리다. (45ms)
    • 3번 기준 (25ms)
  • 컴퓨팅파워, 실제로 한번에 수천수만번회까지 갈 일이 크게 없다는 점을 고려하면 큰 차이는 아니지만, 사소한 팁..!
  • 3번관련하여 주의할 점은... enum 생성자가 호출되기 전에 참조를 시도하면 null 이 발생한다. LazyHolder 패턴으로 극복할 수 있을 듯

2. Enum 으로 Bean 을 찾아보자

  • 비즈니스를 구현하다보면, enum type 에 따라 실행시킬 bean 이 달라지면 구조가 깔끔하겠다.. 하는 경우가 생긴다.
  • 이럴 때, enum 과 bean 을 매핑하는 몇 가지 경우가 있다.
    1. enum 속성으로 String beanName 정의 => spring context 안에서 applicationContext.getBean(type.getBeanName());
    2. enum 속성으로 Class<?> beanType 정의 => spring context 안에서 applicationContext.getBean(type.getBeanType());
    3. EnumMap 으로 enum 과 bean 을 바로 맵핑
Map<OperatingSystemType, OperatingSystemHandler> map = new EnumMap<>(OperatingSystemType.class);
// OperatingSystemHandler 구현체에서 enum type 을 getType 메소드로 명시
for (OperatingSystemHandler handler : operatingSystemHandlerList) {
 map.put(handler.getType(), handler);
}
  • (백만번) 테스트해보면 결과는 다음과 같다.
    • 1번은 2번보다 조금 빠르다. (각각 120ms , 160ms)
      • BeanFactory와 ApplicationContext 의 구현체들의 getBean 이 복잡하기 때문
    • 3번은 1번과 2번보다 5배 이상 빠르다. (약 20ms)
    • (3번에서 EnumMap 대신 HashMap 등을 쓰면 약 35ms)
      • EnumMap이 더 빠른 이유는 enum이 단일객체 key임이 보장되어 해싱 등 작업 불필요)
  • 소소한 차이지만, 성능과 접근뎁스에서 EnumMap 이 가장 우위에 있음을 알 수 있다.



출처: https://sjh836.tistory.com/175?category=679845 [빨간색코딩]