Please let me know about the profiling, once you'll do. If sql generation cache could give any speed-up to the query execution, I will do the required refactoring.
Otherwise we could remove the cache (but still, we will need to work a lot on performances, since in any enterprise environment (as the one we will use DbLinq in our company) 7 seconds for each query are not acceptable (we work in a web environment with many different queries done per request)... Giacomo On Sun, May 17, 2009 at 2:12 PM, Jonathan Pryor <[email protected]> wrote: > 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 *7*755ms *(*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 -~----------~----~----~----~------~----~------~--~---
