자 잠깐 메모이제이션에 대해 생각해보자, 함수를 만들 때, memo라는 변수를 사용 하였다. 그게 왜 문제가 될까?
// 이거 isPrime 함수에 포함 된 변수가 아닌데....
const memo = new Map()
// 엄청 긴 로직
const isPrime = (num) => {
if(memo.has(num)) {
console.log('from memo')
return memo.get(num)
}
// 생략 ...
memo.set(num, res)
return res
}
자 간단히 memo라는 변수를 삭제했다고 생각해보자, 가능성이 없다고 생각하는가? 우리는 몇라인까지 저 변수를 버리에 기억 할 수 있을까? 5라인? 10라인? 100라인?? 모르겠다. 다만, 필요없다고 생각하여 지워질 수 있다.
혹은 다른 함수에서 참조하게 될 지도 모른다. 이건 매우매우 가능성이 높으며, 예방을 하려면 어떻게 해야할까?
const isPrimeFactory = () => {
const memo = new Map()
return (num) => {
if (memo.has(num)) {
console.log('from memo')
return memo.get(num)
}
let count = 0
for (let i = 2; i <= num; i++) {
console.log('tested')
if (num % i === 0) count++
if (count > 1) break
}
const res = count === 1
memo.set(num, res)
return res
}
}
const isPrime = isPrimeFactory();
정말 정말 간단하다 외부에서 직접 접근 할 수 없도록, 함수로 한번 감싸주기만 하면 된다. :)
자 여기서 잠깐 생각해보자 위의 코드의 본질은 무엇인가?
소수 여부를 판단하는 함수이니, 아래의 코드 아닌가?
let count = 0
for (let i = 2; i <= num; i++) {
console.log('tested')
if (num % i === 0) count++
if (count > 1) break
}
const res = count === 1
자 그러면 잠깐 다시 코드를 수정해보자.
const isPrime = (num) => {
let count = 0
for (let i = 2; i <= num; i++) {
console.log('tested')
if (num % i === 0) count++
if (count > 1) break
}
return count === 1
}
const isPrimeFactory = () => {
const memo = new Map()
return (num) => {
if (memo.has(num)) {
console.log('from memo')
return memo.get(num)
}
const res = isPrime(num)
memo.set(num, res)
return res
}
}
const isPrimeMemo = isPrimeFactory();
함수가 늘어났다, 그리고 그거 아는가? 자바스크립트에서 함수는 일급객체로 변수/파라미터/리턴 할 수 있는 값이다. 또 한번 바꿔주도록 하고, 이름도 좀 바꿔보자.
const isPrime = (num) => {
let count = 0
for (let i = 2; i <= num; i++) {
console.log('tested')
if (num % i === 0) count++
if (count > 1) break
}
return count === 1
}
const autoMemo = (orgFn) => {
const memo = new Map()
return (arg) => {
if (memo.has(arg)) {
console.log('from memo')
return memo.get(arg)
}
const res = orgFn(arg)
memo.set(arg, res)
return res
}
}
const isPrimeMemo = autoMemo(isPrime);
자 어떤가? 별로 달라진 것은 없는 코드아닌가? 하지만, 이렇게 바꿈으로써 우리가 얻은것은 꽤나 많다.
const isPrimeMemo = autoMemo(isPrime);
const factorialMemo = autoMemo(factorial);
const gausMemo = autoMemo(gaus);
코드를 위처럼 변경함으로써, 우리는 많은 함수들을 메모이제이션을 지원할 수 있게되었다.
댓글
댓글 쓰기