-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCaching.cs
52 lines (46 loc) · 1.87 KB
/
Caching.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Collections.Generic;
using Serilog;
namespace Sturla.io.Func.CachingOfExpensiveMethodCalls.Console
{
/// <summary>
/// Memoization take a look at https://www.infoq.com/news/2007/01/CSharp-memory
/// </summary>
public static class Caching
{
/// <summary>
/// Here you do recursion, but you remember the value of each Fibonacci/LowerCasing.
/// Thus, instead of 29 Million for 35th Fibonacci you do 37 calculations. And it takes just 0.002 seconds.
///
/// "In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs
/// by storing the results of expensive function calls and returning the cached result when the same inputs occur again."
/// https://en.wikipedia.org/wiki/Memoization
/// </summary>
/// <typeparam name="TArgument"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="function">The expensive method sent in to cache its results.</param>
/// <returns></returns>
public static Func<TArgument, TResult> Memoize<TArgument, TResult>(this Func<TArgument, TResult> function)
{
var methodDictionaries = new Dictionary<string, Dictionary<TArgument, TResult>>();
var name = function.Method.Name;
if (!methodDictionaries.TryGetValue(name, out Dictionary<TArgument, TResult> values))
{
values = new Dictionary<TArgument, TResult>();
Log.Information("MethodName: {name}, ReturnType: {returnType}", name, function.Method.ReturnType);
methodDictionaries.Add(name, values);
}
return a =>
{
// If we have already got value cached from e.g Fibonacci(i) or it has been added to values
// and there is no need to call the expensive function. We already have the result in cache.
if (!values.TryGetValue(a, out TResult value))
{
value = function(a);
values.Add(a, value);
}
return value;
};
}
}
}