I need to get some info passed as a lambda expression to some methods. Basically, it's a way to add information to a database query. A simple example would be:
companyData.GetAll(
where => "SomeField = @SOMEFIELD",
order => "Id",
SOMEFIELD => new Parameter {DbType = DbType.String, Value = "some value"}
)
It's working pretty well, except for the fact that I need to call LambdaExpression.Compile to get the parameter object, which have a big perfomance impact.
To get faster results, I've come with this naive caching test:
class ExpressionCache<T,U>
{
private static ExpressionCache<T, U> instance;
public static ExpressionCache<T, U> Instance
{
get
{
if (instance == null) {
instance = new ExpressionCache<T, U>();
}
return instance;
}
}
private ExpressionCache() { }
private Dictionary<string, Func<T, U>> cache = new Dictionary<string, Func<T, U>>();
public Func<T, U> Get(Expression<Func<T, U>> expression)
{
string key = expression.Body.ToString();
Func<T,U> func;
if (cache.TryGetValue(key, out func)) {
return func;
}
func = expression.Compile();
cache.Add(key, func);
return func;
}
}
This class made a huge difference: from about 35000 milliseconds on 10000 iterations to about 700.
Now comes the question: what kind of problem I will run into using the expression body as the key for the dictionary?