2026년 상식닷컴 선정 식당 & 카페 리스트
최근에 오픈한 호텔을 찾는다면 살펴보세요

자바스크립트에서 함수의 메모이제이션을 구현하는 방법은 무엇인가요?

_____
Q1: 자바스크립트에서 메모이제이션이란 무엇인가요?
A1: 메모이제이션(Memoization)은 함수의 결과를 캐시에 저장하여 동일한 입력값에 대해 함수 호출을 반복하지 않고 저장된 값을 재사용하는 최적화 기법입니다. 이를 통해 중복 계산을 줄이고 성능을 향상시킬 수 있습니다.

---

Q2: 자바스크립트에서 기본적인 메모이제이션 함수는 어떻게 구현하나요?
A2: 가장 간단한 메모이제이션 함수는 내부에 캐시 객체를 만들고, 함수 호출 시 인자를 키로 사용해 결과를 저장하는 방식입니다.

```javascript
function memoize(fn) {
const cache = {};
return function(...args) {
const key = JSON.stringify(args);
if (cache[key]) {
return cache[key];
} else {
const result = fn.apply(this, args);
cache[key] = result;
return result;
}
};
}
```

---

Q3: 위 메모이제이션 함수의 단점은 무엇인가요?
A3: 주요 단점은 다음과 같습니다.
- `JSON.stringify`가 인자 배열을 문자열로 변환하는 데 비용이 발생함.
- 객체나 함수가 인자로 들어오면 키 충돌 또는 올바른 비교가 어려움.
- 캐시가 무한히 커질 수 있고, 메모리 관리가 어렵다는 점.

---

Q4: 복잡한 인자를 가진 함수도 메모이제이션하려면 어떻게 해야 하나요?
A4: 다음과 같은 방법이 있습니다.
- `WeakMap`이나 `Map`을 사용해 객체 참조를 키로 사용하는 방법.
- 재귀적 맵 구조를 사용하여 인자별로 캐시 구조를 세분화하는 방법.
- 외부 라이브러리(lodash.memoize, memoizee 등)를 사용하는 방법.

예시 (객체 인자처리용):

```javascript
function memoize(fn) {
const cache = new Map();
return function(...args) {
let currentCache = cache;
for (const arg of args) {
if (!currentCache.has(arg)) {
currentCache.set(arg, new Map());
}
currentCache = currentCache.get(arg);
}
if (!currentCache.has('result')) {
currentCache.set('result', fn.apply(this, args));
}
return currentCache.get('result');
};
}
```

---
Q5: 메모이제이션 시 주의해야 할 점은 무엇인가요?
A5:
- 메모이제이션은 순수 함수(pure function)에 적합합니다. 즉, 같은 인자에 대해 항상 같은 결과를 반환해야 합니다.
- 부작용이 있거나 상태에 의존하는 함수는 적합하지 않습니다.
- 메모리 누수를 방지하려면 캐시 크기 제한이나 만료 정책을 적용하는 것이 좋습니다.
- 비동기 함수는 보통 `Promise`를 캐시하더라도 결과가 변할 수 있어 주의가 필요합니다.

---

Q6: 제너릭한 메모이제이션 라이브러리나 함수가 있나요?
A6: 대표적으로 `lodash`의 `_.memoize`가 자주 사용됩니다. 사용법은 다음과 같습니다.

```javascript
const _ = require('lodash');

const memoizedFn = _.memoize(function(x) {
// 복잡한 계산
return x * x;
});
```

커스텀 키 생성 함수도 가능해 복잡한 인자 처리에 활용할 수 있습니다.

---

Q7: 비동기 함수도 메모이제이션 할 수 있나요?
A7: 가능합니다. 비동기 함수가 반환하는 `Promise`를 캐시에 저장하면 됩니다. 예:

```javascript
function memoizeAsync(fn) {
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const promise = fn.apply(this, args);
cache.set(key, promise);
return promise;
};
}
```

단, 비동기 함수가 실패하거나 외부 상태 변경 시 캐시된 결과가 문제가 될 수 있으므로 주의해야 합니다.

---

Q8: 메모이제이션을 언제 사용하면 좋은가요?
A8: 다음과 같은 경우에 사용하면 좋습니다.
- 동일한 인자에 대한 함수 호출이 반복적으로 발생하는 경우
- 계산 비용이 높은 순수 계산 함수 (예: 피보나치 수열, 조합 계산 등)
- 렌더링 최적화나 리액트 등에서 훅 최적화 시

---

요약
- 메모이제이션은 함수 결과를 저장해 중복 계산을 피하는 기법
- 가장 간단한 구현은 인자를 문자열화해 키로 사용하는 방식
- 객체 인자 처리 및 메모리 관리, 비동기 함수 등 상황에 따라 구현 방법 달라짐
- 순수 함수에 적합하며 부작용 함수에는 권장하지 않음
- Lodash 같은 라이브러리 활용 가능

필요시 상황에 맞는 방법을 선택해 사용하세요.
메모이제이션(Memoization)은 함수의 결과를 캐싱하여 동일한 입력에 대해 반복적으로 계산하는 것을 방지하는 최적화 기법입니다.

자바스크립트에서 메모이제이션을 구현하는 방법은 여러 가지가 있지만, 기본적인 원리는 함수의 결과를 저장하고, 동일한 입력이 주어졌을 때 저장된 결과를 반환하는 것입니다.

이를 통해 성능을 크게 향상시킬 수 있습니다.

메모이제이션 구현 방법 1. 기본 메모이제이션 함수 구현 : 가장 간단한 메모이제이션 구현은 객체를 사용하여 함수의 입력과 출력을 저장하는 것입니다.

아래는 기본적인 메모이제이션을 구현한 예제입니다.

```javascript function memoize(fn) { const cache = {}; return function(...args) { const key = JSON.stringify(args); // 인자를 문자열로 변환하여 키로 사용 if (cache[key]) { return cache[key]; // 캐시에서 결과 반환 } const result = fn(...args); // 결과 계산 cache[key] = result; // 캐시에 결과 저장 return result; }; } // 예시로 사용할 재귀적 피보나치 함수 function fibonacci(n) { if (n <= 1) return n; return fibonacci(n - 1) + fibonacci(n -

2); } const memoizedFibonacci = memoize(fibonacci); console.log(memoizedFibonacci(

10)); // 55 console.log(memoizedFibonacci(

10)); // 캐시된 결과 사용 ``` 위의 코드에서 `memoize` 함수는 입력 함수 `fn`을 받아서 캐시를 관리하는 새로운 함수를 반환합니다.

이 새로운 함수는 인자를 문자열로 변환하여 캐시에서 결과를 찾고, 없을 경우 원래 함수를 호출하여 결과를 계산한 후 캐시에 저장합니다.



2. 다양한 인자 처리 : 위의 예제는 단순한 인자에 대해서는 잘 작동하지만, 배열이나 객체와 같은 복잡한 데이터 구조를 사용할 경우, `JSON.stringify`를 사용한 키 생성이 충돌을 일으킬 수 있습니다.

이 경우, 더 정교한 방법으로 키를 생성해야 합니다.

```javascript function memoize(fn) { const cache = new Map(); return function(...args) { const key = args.map(arg => (typeof arg === 'object' ? JSON.stringify(arg) : arg)).join('|'); if (cache.has(key)) { return cache.get(key); } const result = fn(...args); cache.set(key, result); return result; }; } ``` 여기서는 `Map`을 사용하여 키-값 쌍을 저장하고, 객체나 배열을 문자열로 변환하여 키를 생성합니다.



3. 메모이제이션의 한계 : 메모이제이션은 모든 경우에 유용하지 않습니다.

예를 들어, 입력이 매우 다양하거나, 함수의 결과가 입력에 따라 매번 달라지는 경우(부수 효과가 있는 경우)에는 메모이제이션이 적합하지 않을 수 있습니다.

또한, 메모리 사용량이 증가할 수 있으므로, 캐시를 적절히 관리하는 것이 중요합니다.



4. 캐시 크기 제한 : 메모이제이션을 사용할 때는 캐시의 크기를 제한하는 것이 좋습니다.

이를 위해 LRU(Least Recently Used) 캐시 알고리즘을 구현할 수 있습니다.

LRU 캐시는 가장 오래된 항목을 제거하여 새로운 항목을 추가하는 방식으로 작동합니다.

```javascript class LRUCache { constructor(limit) { this.cache = new Map(); this.limit = limit; } get(key) { if (!this.cache.has(key)) return null; const value = this.cache.get(key); this.cache.delete(key); // 최근 사용으로 업데이트 this.cache.set(key, value); return value; } set(key, value) { if (this.cache.has(key)) { this.cache.delete(key); // 기존 항목 삭제 } else if (this.cache.size === this.limit) { this.cache.delete(this.cache.keys().next().value); // 가장 오래된 항목 삭제 } this.cache.set(key, value); } } function memoize(fn) { const cache = new LRUCache(100); // 캐시 크기 100으로 설정 return function(...args) { const key = JSON.stringify(args); const cachedResult = cache.get(key); if (cachedResult !== null) { return cachedResult; } const result = fn(...args); cache.set(key, result); return result; }; } ``` 결론 메모이제이션은 성능 최적화에 매우 유용한 기법입니다.

자바스크립트에서 메모이제이션을 구현하는 방법은 다양하며, 함수의 특성과 사용 사례에 따라 적절한 방법을 선택해야 합니다.

캐시의 크기를 관리하고, 입력 데이터의 특성을 고려하여 메모이제이션을 적용하면, 애플리케이션의 성능을 크게 향상시킬 수 있습니다.

작성자: 박하윤 [비회원] | 작성일자: 1년 전 2024-09-10 08:37:03
조회수: 144 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.