정보실

웹학교

정보실

javascript JavaScript에서의 메모 소개

본문

이 게시물의 비디오 버전을 만들었습니다! 이 방법으로 자습서 컨텐츠를 사용하려면 YouTube에서 확인하십시오.


소개 


Memoization은 많은 프로그래밍 언어에서 중복, 고가의 함수 호출 횟수를 줄이기 위해 사용되는 최적화 기술입니다. 이는 입력을 기준으로 함수의 반환 값을 캐싱하여 수행됩니다. 이 글에서는 차선책이지만 교육적으로 유익한 JavaScript 함수 메모기를 만듭니다.


https://nick.scialli.me/an-introduction-to-memoization-in-javascript/ 


첫째, 암기하는 비싼 함수 


기억해야 할 기능이 있습니다. 매우 비효율적 인 방법으로 숫자의 제곱을 찾습니다.

const inefficientSquare = num => {
  let total = 0;
  for (let i = 0; i < num; i++) {
    for (let j = 0; j < num; j++) {
      total++;
    }
  }
  return total;
};

이 기능을 동일한 값으로 실행할 수 있으며 매번 실행하는 데 시간이 걸립니다.

const start = new Date();
inefficientSquare(40000);
console.log(new Date() - start);
// 1278

const start2 = new Date();
inefficientSquare(40000);
console.log(new Date() - start2);
// 1245


매번 1 초 이상


Memoizer 용 의사 코드 작성 


코드를 작성하기 전에 메모기를 통해 추론합시다.

  • 함수를 입력으로 참조합니다
  • 함수를 반환합니다 (따라서 정상적으로 사용됩니다)
  • 이전 함수 호출의 결과를 보유하기 위해 일종의 캐시를 작성합니다.
  • 나중에 함수를 호출 할 때 캐시 된 결과가 있으면 이를 반환합니다.
  • 캐시 된 값이 존재하지 않으면 함수를 호출하고 결과를 캐시에 저장합니다

실제 코드 시간 


위의 의사 코드 개요를 구현했습니다. 소개에서 언급 했듯이 이것은 차선책이므로 프로덕션 환경에서는 사용하지 않아야 합니다. 왜 그런지 설명하겠습니다!

// Takes a reference to a function
const memoize = func => {
  // Creates a cache of results
  const results = {};
  // Returns a function
  return (...args) => {
    // Create a key for results cache
    const argsKey = JSON.stringify(args);
    // Only execute func if no cached value
    if (!results[argsKey]) {
      // Store function call result in cache
      results[argsKey] = func(...args);
    }
    // Return cached value
    return results[argsKey];
  };
};


이 구현에서 가장 차선책이며 프로덕션 코드에서 사용하지 않는 이유는 JSON.stringify를 사용하여 결과 캐시에 키를 만드는 것입니다. JSON.stringify의 가장 큰 문제는 함수 및 기호 (및 JSON에서 찾을 수 없는 항목)와 같은 특정 입력을 직렬화 하지 않는다는 것입니다.


고가의 함수에서 Memoizer 테스트 


비효율적인 스퀘어 예제를 복제 해 보겠습니다. 이번에는 memoizer를 사용하여 결과를 캐시 하겠습니다.

const memoize = func => {
  const results = {};
  return (...args) => {
    const argsKey = JSON.stringify(args);
    if (!results[argsKey]) {
      results[argsKey] = func(...args);
    }
    return results[argsKey];
  };
};

const inefficientSquare = memoize(num => {
  let total = 0;
  for (let i = 0; i < num; i++) {
    for (let j = 0; j < num; j++) {
      total++;
    }
  }
  return total;
});

const start = new Date();
inefficientSquare(40000);
console.log(new Date() - start);
// 1251

const start2 = new Date();
inefficientSquare(40000);
console.log(new Date() - start2);
// 0


성공! 동일한 입력으로 inefficientSquare를 두 번째 호출 할 때 재 계산하는 데 시간이 걸리지 않습니다. 단순히 캐시 된 값을 객체에서 가져옵니다.



순수한 함수 만 기억하십시오! 


메모 화는 훌륭하지만 함수가 순수한 경우에만 작동합니다. 다시 말해, 함수의 반환 값이 입력보다 많은 값에 의존하는 경우 해당 입력에 대해 캐시 된 값이 항상 정확하지는 않습니다. 또한 함수에 부작용이 있는 경우, 메모리는 이를 복제하지 않고 궁극적으로 반환 된 함수 값을 반환합니다.


결론 


이제 메모를 사용하는 방법과 이유를 잘 알고 있어야 합니다! 우리의 메모 기능은 차선책이지만, 훨씬 더 많은 기능을 수행 할 수 있는 타사 라이브러리가 많이 있습니다. 기억하고 있는 함수가 순수한지 확인하십시오!



  • 트위터로 보내기
  • 페이스북으로 보내기
  • 구글플러스로 보내기
  • 카카오톡으로 보내기

페이지 정보

조회 23회 ]  작성일19-08-25 10:10

웹학교