자바스크립트 메모이제이션 패턴

mollog·2021년 1월 30일
0

본 내용의 일부는 자바스크립트 패턴과 테스트 서적에서 발취한 내용과 코드입니다.

메모이제이션 패턴이란

결과를 메모리에 기억시켜 다음 작업에서 재사용하는 자바스크립트 패턴입니다.

예시 상황

나는 컨퍼런스 기간에 특정 업체에 고용된 단기 프리랜서 개발자이고,
컨퍼런스에 찾아온 손님들이 키오스크로 컨퍼런스 근처 식당을 찾을 수 있도록 서비스를 제공하는 개발을 맡았다고 가정합니다. 🍕
키오스크로 식당을 찾아주는 api가 호출될 때마다 비용이 발생하고 있고, 업체는 나에게 해당 비용을 절감할 방안을 요구합니다.

해결 방안

개발자인 나는 검색한 결과를 어딘가에 저장해놓고 다른 참가자가 같은 요리를 검색하면 저장한 데이터를 다시 반환하는 방법을 제시합니다.

// 컨퍼런스라는 객체가 있다고 가정한다
var Conference = Conference || {};

// 이 컨퍼런스 객체는 memoizedRestaurantApi 라는 메서드를 갖는다
// memoizedRestaurantApi 함수는 서드파티api 함수를 매개변수로 갖는다고 가정한다
Conference.memoizedRestaurantApi = function(thirdPartyApi) {
  'use strict';
	
  // 서드파티api 함수를 변수로 선언한다
  var api = thirdPartyApi;
  // 캐싱할 공간은 변수로 선언한다
  var cache = {};

  return {
    // 레스토랑 리스트를 가져오는 함수 구현부는 아래와 같다
    getRestaurants: function(cuisine) {
      // 캐시에 cuisine(검색값)이라는 검색값이 이미 존재한다면
      if (cache.hasOwnProperty(cuisine)) {
        // api를 호출하지 않고 캐시에 있는 값을 사용한다 (메모이제이션)
        return cache[cuisine];
      }
      // 캐시에 cuisine(검색값)이라는 검색값이 이미 존재하지 않는다면 api 호출한다
      var returnedPromise = api.getRestaurantsNearConference(cuisine);
      // api 호출 결과값을 캐시에 저장한다
      cache[cuisine] = returnedPromise;
      // api 호출 결과를 리턴한다
      return returnedPromise;
    }
  };
};

이미 개발된 서드파티api를 다시 들어내지 않고 memoizedRestaurantApi 라는 함수로 감싼 뒤 캐싱할 공간을 만들어줌으로서 공수도 줄이고 호출 비용도 줄이는 효과를 얻어냅니다. 👍

😶
메모이제이션이 어떤 상황에서 유용하게 사용되는지는 구체적인 예시를 통해 알게 되었지만 조금 더 쉬운 코드를 보며 사용법을 익히고자 검색해 보니 복잡한 연산이 들어가는 작업에 주로 사용한다고 합니다.

조금 더 쉬운 예시 코드

function sqrt(arg) {
    return Math.sqrt(arg);
}
log(sqrt(4)) // 2
log(sqrt(9)) // 3

위와 같은 제곱근 함수가 있고 이 함수를 메모이제이션 패턴으로 리팩토링 한다면 아래와 같습니다.

function sqrt(arg) {
    // sqrt 함수에 cache 라는 프로퍼티가 없다면 빈 객체를 지정해 준다
    if (!sqrt.cache) {
        sqrt.cache = {}
    }
    // sqrt 함수의 cache 라는 프로퍼티의 [arg] 값이 없다면 (메모이제이션된 값이 없다면)
    if (!sqrt.cache[arg]) {
        // 해당 값을 기억시켜준다
        return sqrt.cache[arg] = Math.sqrt(arg)
    }
    // sqrt 함수의 cache 라는 프로퍼티의 [arg] 값이 있다면 (메모이제이션된 값이 있다면)
    // 연산하지 않고 해당 값을 바로 리턴한다
    return sqrt.cache[arg]
}

정리

메모이제이션의 목표는 속도입니다. 그리고 메모이제이션은 속도를 위해 저장공간(메모리)을 사용합니다.
실행 시간이 줄어드는 장점이 있지만 메모리를 버리기 때문에 입력 범위가 제한된 함수에 사용해야 합니다.
즉, 함수 연산 결과 값이 제곱근 예시 케이스와 같이 확실하게 고정된 값인 경우에 사용합니다.

0개의 댓글