Memoization

メモイゼーション

メモイゼーションを分かりやすく

メモイゼーションは、コンピュータープログラミングにおける最適化の一種で、特定の関数の出力をキャッシュして、同じ入力で再度呼び出されたときに計算時間を節約するテクニックです。だいぶ難しく聞こえますよね。

例えば、同じお店で毎日ランチを食べるとしましょう。最初の数日はメニューをじっくり見て何を食べるか決めますが、何度も行くとどの料理がどんな味か覚えるので、考える時間が短くなりますよね。これがメモイゼーションの考え方です。

メモイゼーションの歴史的変遷

メモイゼーションは、元々は関数型プログラミング言語の一部として開発され、その後、多くの言語で利用可能になりました。JavaScriptやTypeScriptでも利用可能となり、特にReactの世界ではuseMemouseCallbackといったフックを通じてメモイゼーションが実現できます。これにより、Reactのコンポーネントのパフォーマンス最適化が容易になりました。

メモイゼーションとJamstackの関係

メモイゼーションはJamstackのプロジェクトにも非常に有益です。Jamstackでは、静的なサイト生成が主であるため、サーバーサイドでの計算負荷を減らすことはあまり重要ではありません。しかし、クライアントサイドでは違います。クライアントサイドで動的な処理が必要な場合、その処理速度はユーザー体験に直接影響します。そこでメモイゼーションが役立ちます。高価な計算やAPIからのレスポンスなど、再利用可能な結果をキャッシュしておくことで、ユーザー体験を向上させることができます。

メモイゼーションを使うメリット

処理速度の向上

前述の通り、一度計算した結果を再利用することで処理速度が向上します。これにより、ユーザー体験の向上やサーバーリソースの節約に繋がります。

サーバーリソースの節約

再計算を行わないことで、CPUやメモリなどのサーバーリソースを節約することが可能です。

メモイゼーションを実装

メモイゼーションの一例として、ReactのuseMemoフックを用いたシンプルなコンポーネントを見てみましょう。

import React, { useMemo } from 'react';

type Props = {
  numbers: number[];
};

const Component: React.FC<Props> = ({ numbers }) => {
  const sortedNumbers = useMemo(() => {
    console.log('Sorting...');
    return numbers.sort((a, b) => a - b);
  }, [numbers]);

  return (
    <div>
      {sortedNumbers.map((num) => (
        <p key={num}>{num}</p>
      ))}
    </div>
  );
};

export default Component;

上記のコードでは、配列の数字をソートする処理をuseMemoフックでラップしています。このソート処理は計算コストが高いため、毎回再計算するとパフォーマンスに影響します。しかしuseMemoを用いることで、numbersプロパティが変更されない限り再計算を防ぐことができます。凄くないですか?

メモイゼーションを学ぶ

以下は、メモイゼーションについて学ぶのに役立つリソースのリストです。

タイトル 説明
React Docs - useMemo React公式ドキュメンテーションのuseMemoについてのページ。詳細な説明と例があります。
MDN Docs - Memoization MDNのメモイゼーションについての記事。基本的な概念とその使用例があります。
Practical Guide to Memoization in JavaScript JavaScriptでのメモイゼーションの詳細なガイド。詳細な説明と具体的な例があります。