利用Dictionary模拟.net缓存

手册/FAQ (519) 2016-04-08 13:38:53

在计算机的硬件设计中,有一个被反复使用的思想——缓存。同样,在软件设计中,这个思想也可以用来解决数据读取非常耗时带来的性能问题(当然,在时间和空间上,我们要寻找一个平衡点)。

首先来看理想的缓存应该是怎么描述的:

1.static Func<T, R> Cache<T, R>(Func<T, R> func)  
2.      {  
3.  
4.          var mem = new Dictionary<T, R>();  
5.          return x =>  
6.          {  
7.  
8.              if (!mem.ContainsKey(x))  
9.              {  
10.                  Console.WriteLine("未缓存,正在缓存!");  
11.                  mem[x] = func(x);  
12.  
13.              }  
14.              return mem[x];  
15.  
16.          };  
17.      }  

        大致就是给进去一个T,然后吐出来一个R。

        run下看看:

1.#region 利用字典来实现对函数的缓存  
2.  
3.              var cacheFunc = Cache<int, int>(DoSomeTing);  
4.              Console.WriteLine(cacheFunc(10));  
5.              Console.WriteLine(cacheFunc(5));  
6.              Console.WriteLine(cacheFunc(10));  
7.              Console.ReadKey();  
8. 
9.#endregion  

         其中,DoSomeThing是可以是一个读取数据库的操作,复杂的计算操作等等,在这里,只写了个简单的意思下:
1.static int DoSomeTing(int a)  
2.        {  
3.  
4.            return a * a;  
5.  
6.  
7.        }  
        
        接下来的函数就比较有意思了,试想下,如果dictionary的value值为一个字典类型数据呢?

1.static Func<int, int, int> DoSomeTing()  
2.       {   
3.         
4.           var dic=new Dictionary<int,Dictionary<int,int>>();  
5.           return (a,b)=>{  
6.             
7.               if (!dic.ContainsKey(a))  
8.            {  
9.                   Console.WriteLine("a为{0}和b为{1}未进行缓存!",a,b);  
10.                   dic[a]=new Dictionary<int,int>();  
11.                   dic[a][b]=a+b;  
12.  
13.            }else  
14.            {  
15.                   if (!dic[a].ContainsKey(b))  
16.                {  
17.                       Console.WriteLine("a为{0}已经缓存,b为{1}未进行缓存,正在缓存中",a,b);  
18.                       dic[a][b]=a+b;  
19.       
20.                }  
21.            }  
22.  
23.               return dic[a][b];  
24.             
25.           };  
26.       }  

  run下看看:
      
1.//var sfunc = DoSomeTing();  
2.               var sfunc=Cache<int,Func<int,int>>(x=>Cache<int,int>(y => x+y));  
3.  
4.               Console.WriteLine(sfunc(10)(5));  
5.               Console.WriteLine(sfunc(5)(10));  
6.               Console.WriteLine(sfunc(10)(5));  
7.               Console.ReadKey();  

THE END