「関数のメモ化」というテクニックがあるみたい。
初めて知った。メソッドの引数と結果をキャッシュしているのかぁ。クロージャの「環境を包み込む」特徴を上手く使って、キャッシュ用変数を外部から見えなくしているところがステキ。
using System; using System.Collections.Generic; using System.Linq; using System.Threading; namespace MemoSample { class Program { // 関数をメモ化する private static Func<TArg, TResult> Memoization<TArg, TResult>(Func<TArg, TResult> source) { var dic = new Dictionary<TArg, TResult>(); return x => { if (!dic.ContainsKey(x)) { // 初めて渡される引数のときは計算 dic[x] = source(x); } return dic[x]; }; } private static int HeviyCalc(int n) { Thread.Sleep(1000); return n * n; } static void Main(string[] args) { var func = Memoization<int, int>(HeviyCalc); foreach (var i in Enumerable.Range(0, 5)) { Console.WriteLine(func(i)); } foreach (var i in Enumerable.Range(0, 5)) { Console.WriteLine(func(i)); } Console.ReadLine(); } } }
ジェネリックで実装してみたけど、もっと汎用的に実装できるはず。