JavaScript/JS 활용 & etc..

메모제이션(Memoization) 패턴

jaiyah 2016. 10. 13. 09:29

함수 프로퍼티 - Memoization Pattern(메모제이션 패턴)

함수는 객체이기 때문에 프로퍼티를 가질 수 있습니다.

사실 함수는 처음부터(생성될 때부터) 프로퍼티와 메서드를 가지고 있습니다.

예를 들어, 각 함수는 어떤 문법으로 생성하는 자동으로 length 프로퍼티를 가지고 있습니다.

이 프로퍼티는 함수가 받는 인자의 개수를 값으로 가지게 됩니다.


javascript
function func(a, b, c) {}
console.log(func.length); // 3 이 기록된다.

언제든지 함수에 사용자 정의 프로퍼티를 추가할 수 있습니다.

함수에 프로퍼티를 추가하여 결과(반환 값)을 캐시하면 다음 호출 시점에 복잡한 연산을 반복하지 않을 수 있습니다.

이런 활용 방법을 메모제이션(Memoization) 패턴이라고 합니다.




다음 예제에서는 myFunc 함수에 cache 프로퍼티를 생성하고, 이 프로퍼티는 일반적인 프로퍼티처엄 myFunc.cache 와 같은 형태로 접근할 수 있습니다.

cache 프로퍼티는 함수로 전달된 param 매개변수를 키로 사용하고 계산의 결과를 값으로 가지는 객체(해시)입니다.

결과 값은 필요에 따라 복잡한 데이터 구조로 저장할 수도 있습니다.

javascript
var myFunc = function (param) {
    if (!myFunc.cache[param]) {
        var result = {};

        // 비용이 많이 드는 로직 수행..

        myFunc.cache[param] = result;
    }
    return myFunc.cache[param];
};

// 캐시 저장 공간
myFunc.cache = {};


위 코드는 myFunc 함수가 param 이라는 단 하나의 매개변수를 받는다고 가정합니다.

이 매개 변수는 문자열과 같은 윈시 데이터 타입이라고 가정합니다.

만약 더 많은 매개변수와 더 복잡한 타입을 갖는다면 일반적으로 직렬화하여 해결할 수 있습니다.

예를 들어, 객체 인자를 JSON 문자열로 직렬화하고 이 문자열을 cache 객체에 키로 사용할 수 있습니다.

javascript
var myFunc = function () {
    var cachekey = JSON.stringify(Array.prototype.slice.call(arguments)),
        result;

    if (!myFunc.cache[cachekey]) {
        result = {};

        // 비용이 많이 드는 로직 수행..

        myFunc.cache[cachekey] = result;
    }

    return myFunc.cache[cachekey];

};

// 캐시 저장 공간
myFunc.cache = {};

직렬화하면 객체를 식별할 수 없게 되는 것을 주의해야 합니다.

만약 같은 프로퍼티를 가지는 두개의 다른 객체를 직렬화하면, 이 두 객체는 같은 캐시 항목을 공유하게 될 것입니다.




Jaehee's WebClub