Even if we change InputParameterExpression so that it accepts the object
from which to retrieve a value instead of caching the value itself
(which will be required for implementing CompiledQuery), we have a more
important profiling question:

Which takes more time: the expression tree generation, the optimization
passes, or the SQL generation itself?

This is important, because if we continue using QueryCache but change it
to accept parameters from a new expression tree (which would be needed
to prevent caching the values with the InputParameterExpression), then
we'll still need to go through the expression tree generation phase,
just so that we can later extract the current parameter values, before
we continue to the SQL generation phase.

I, of course, haven't yet profiled this.  (Perhaps I will on Monday.)

But I do know that expression trees are slow.

How slow?  Ever hear of "static reflection."  It's a way to get
Reflection information in a compiler-checked fashion.  (Google it if you
haven't seen it before.)  For example:

        static class Reflection {
                public static MethodInfo GetMethod (Expression lambda)
                {
                        LambdaExpression le = lambda as LambdaExpression;
                        if (le == null)
                                throw new ArgumentException ("lambda", "Not a 
LambdaExpression.");
                        MethodCallExpression mce = le.Body as 
MethodCallExpression;
                        if (mce == null)
                                throw new ArgumentException ("lambda", "Does 
not contain a MethodCallExpression.");
                        return mce.Method;
                }
        }
        
        static class Reflection<T> {
                public static MethodInfo GetMethod<S,R> (Expression<Func<S,R>> 
lambda)
                {
                        return Reflection.GetMethod(lambda);
                }
        }

Usage is really cool:

        // Gets the MethodInfo for string.CompareTo(string):
        var readKey = Reflection<string>.GetMethod(s => s.CompareTo("foo"));
        // vs.
        var oldReadKey = typeof(string).GetMethod("CompareTo(System.String)");

Performance, on the other hand, sucks.  For my stupid test,
Type.GetMethod() is ~4481ms.  Reflection<T>.GetMethod() is 7755ms (for
1000000 iterations), so 75% slower.  (It gets worse if the class has
fewer methods; on another class with only 15 members, Type.GetMethod()
was ~1000ms, while static reflection was over 5000ms, again for 1000000
iterations.)

Look at the above code.  The overhead isn't in parsing the expression
tree (which is what Reflection.GetMethod() does), the overhead is in
generating the expression tree.

Our SQL generation is basically just string concats and appends.  Again,
I haven't profiled it, but I really, really, doubt that our SQL
generation will be slower than either the expression tree generation or
the parsing.  I'm not sure it's sensible to try to just cache the
results of SQL generation, though it may be sensible to try to cache the
results of our "optimized" expression types.

 - Jon

On Sun, 2009-05-17 at 11:49 +0100, Giacomo Tesio wrote:

> I'm still analizing the question.
> 
> 
>         QueryCache is busted.  The only way to make it work is to do
>         what was originally done (make values part of the cached
>         values), which results in large memory use as every query
>         variation is stored uniquely.
> 
> If InputParameterExpression would Expression<Func<Expression, object>>
> containing a lambda able to find the parameter value in the
> expression, this would allow to store input parameters expressions in
> the select query and refilling parameters' values with the one
> provided current expression (without revisiting the tree).
> 
> I really think that, since our sql generation process take much time,
> we should try this approach (which require adding an
> Expression<Func<Expression, object>> to many
> ExpressionDispatcher.Analizer method, I think...)
> 
> 
> Giacomo
> 
> 
> (PS I'm not sure to have been clear)
> 
> > 

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"DbLinq" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/dblinq?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to