빨간색코딩

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

Java

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

빨간색소년 2019. 12. 13. 15:13

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

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

  • 장르, 카테고리, 각종 컨텐츠 타입 등 enum 의 활용은 무궁무진하다. enum 을 잘 선언했다면, enum 을 잘 찾는 것도 중요하다

  • 예를들어 DB에 enum name 이 아닌.. 무언가 코드값만 저장하고, 꺼내쓸 때 코드를 enum 으로 바꾸는 상황을 가정해보자.

    • 다른 예제로는 API 응답값 내 코드를 우리 서비스의 enum 으로 바꿔쳐야한다던지..
  • 아래에서는 enum 을 찾아내는 3가지 예제 코드들이다.

      @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 이 가장 우위에 있음을 알 수 있다.
Comments