Sorry Paul, I'm not going to reply anymore. Write a test, write a patch and submit it if you think that using type converters is a better option.
On Sat, Mar 7, 2009 at 15:32, webpaul <[email protected]> wrote: > > Type converter is still faster than dictionary cached LCG (without > overflow problem solved) and I'm not even caching the type converter > yet... The LCG solution does handle the overflow condition gracefully > and I don't fully understand how it isn't overflowing, can you explain > how what you are doing doesn't fail when converting int.MaxValue to a > byte? > > Also, how do you guys handle multi-key dictionaries typically? I have > a way but am curious how you usually do it. > > On Mar 6, 10:02 am, Simone Busoli <[email protected]> wrote: > > Try caching the LCG comparer, you'll be surprised. > > > > > > > > On Fri, Mar 6, 2009 at 16:46, webpaul <[email protected]> wrote: > > > > > This one takes 1000ms vs 6500ms but it handles one of the types being > > > an overflow for the other. I couldn't find a way to detect if there > > > will be an overflow for a specific value without actually catching the > > > overflow exception which makes this take much longer. Any ideas? > > > > > class Program > > > { > > > static void Main(string[] args) > > > { > > > RunComparisons(CreateComparerLCG); > > > RunComparisons(CreateComparerTypeConverter); > > > } > > > > > //Comparison types > > > > > private static Func<object, object, bool> > > > CreateComparerTypeConverter(Type firstType, Type secondType) > > > { > > > if (firstType == secondType) > > > return Equals; > > > > > TypeConverter converterFirstType = > > > TypeDescriptor.GetConverter(firstType); > > > TypeConverter converterSecondType = > > > TypeDescriptor.GetConverter(secondType); > > > > > return delegate(object first, object second) > > > { > > > try > > > { > > > return object.Equals( > > > first, > > > converterFirstType.ConvertTo(second, > > > firstType) > > > ); > > > } > > > catch (OverflowException) > > > { > > > return object.Equals( > > > second, > > > converterSecondType.ConvertTo(first, > > > secondType) > > > ); > > > } > > > }; > > > } > > > > > private static Func<object, object, bool> CreateComparerLCG > > > (Type firstType, Type secondType) > > > { > > > if (firstType == secondType) > > > return Equals; > > > > > var firstParameter = Expression.Parameter(typeof(object), > > > "first"); > > > var secondParameter = Expression.Parameter(typeof(object), > > > "second"); > > > > > var equalExpression = Expression.Equal(Expression.Convert > > > (firstParameter, firstType), > > > Expression.Convert(Expression.Convert(secondParameter, > > > secondType), firstType)); > > > > > return Expression.Lambda<Func<object, object, bool>> > > > (equalExpression, firstParameter, secondParameter).Compile(); > > > } > > > > > private static void RunComparisons(Func<Type, Type, > > > Func<object, object, bool>> createComparer) > > > { > > > List<Comparison> comparisonsToMake = new List<Comparison> > > > { > > > new Comparison { item = (byte)1, otherItem = (int)1 }, > > > new Comparison { item = (int)1, otherItem = (long)1 }, > > > new Comparison { item = (long)1, otherItem = (float) > > > 1 }, > > > new Comparison { item = (float)1, otherItem = (double) > > > 1 }, > > > new Comparison { item = (byte)byte.MaxValue, otherItem > > > = (int)int.MaxValue, expectedValue = false }, > > > }; > > > > > Program program = new Program(); > > > > > Stopwatch watch = new Stopwatch(); > > > watch.Start(); > > > for (int i = 0; i < 10000; i++) > > > { > > > foreach (var comparison in comparisonsToMake) > > > { > > > if (program.Compare(comparison, createComparer) != > > > comparison.expectedValue) > > > throw new ApplicationException("Comparison > > > didn't work"); > > > } > > > }; > > > watch.Stop(); > > > Console.WriteLine("All comparisons took " + > > > watch.ElapsedMilliseconds + "ms"); > > > } > > > > > private class Comparison > > > { > > > public object item; > > > public object otherItem; > > > public bool expectedValue = true; > > > } > > > > > private bool Compare(Comparison comparison, Func<Type, Type, > > > Func<object, object, bool>> createComparer) > > > { > > > object item = comparison.item; > > > object otherItem = comparison.otherItem; > > > > > if (item == null | otherItem == null) > > > return item == null & otherItem == null; > > > > > var equalityComparer = createComparer(item.GetType(), > > > otherItem.GetType()); > > > > > return equalityComparer(item, otherItem); > > > } > > > > > } > > > > > On Mar 6, 9:23 am, webpaul <[email protected]> wrote: > > > > This does it in 93ms vs. 6500ms on my box, could be improved with a > > > > Dictionary as well. Also, it always converts to the first type so if > > > > you compare byte.MaxValue with int.MaxValue you get an exception. It > > > > should convert to the largest type so I'll see what I can do on that > > > > as well. > > > > > > private static Func<object, object, bool> > > > > CreateComparerTypeConverter(Type firstType, Type secondType) > > > > { > > > > if (firstType == secondType) > > > > return Equals; > > > > > > TypeConverter converterFirstType = > > > > TypeDescriptor.GetConverter(firstType); > > > > TypeConverter converterSecondType = > > > > TypeDescriptor.GetConverter(firstType); > > > > > > return delegate(object first, object second) > > > > { > > > > return > > > > object.Equals( > > > > converterFirstType.ConvertTo(first, > > > > firstType), > > > > converterFirstType.ConvertTo( > > > > converterSecondType.ConvertTo(second, > > > > secondType), > > > > firstType > > > > ) > > > > ) > > > > ; > > > > }; > > > > } > > > > > > On Mar 6, 9:10 am, webpaul <[email protected]> wrote: > > > > > > > It's pretty slow as is - takes 6.5 seconds for 10K iterations. I'm > > > > > going to try it a few different ways and see which is fastest. > > > > > > > class Program > > > > > { > > > > > static void Main(string[] args) > > > > > { > > > > > RunComparisons(CreateComparerLCG); > > > > > } > > > > > > > //Comparison types > > > > > > > private static Func<object, object, bool> CreateComparerLCG > > > > > (Type firstType, Type secondType) > > > > > { > > > > > if (firstType == secondType) > > > > > return Equals; > > > > > > > var firstParameter = > Expression.Parameter(typeof(object), > > > > > "first"); > > > > > var secondParameter = > Expression.Parameter(typeof(object), > > > > > "second"); > > > > > > > var equalExpression = > Expression.Equal(Expression.Convert > > > > > (firstParameter, firstType), > > > > > > Expression.Convert(Expression.Convert(secondParameter, > > > > > secondType), firstType)); > > > > > > > return Expression.Lambda<Func<object, object, bool>> > > > > > (equalExpression, firstParameter, secondParameter).Compile(); > > > > > } > > > > > > > private static void RunComparisons(Func<Type, Type, > > > > > Func<object, object, bool>> createComparer) > > > > > { > > > > > List<Comparison> comparisonsToMake = new > List<Comparison> > > > > > { > > > > > new Comparison { item = (byte)1, otherItem = (int)1 > }, > > > > > new Comparison { item = (int)1, otherItem = (long)1 > }, > > > > > new Comparison { item = (long)1, otherItem = > (float) > > > > > 1 }, > > > > > new Comparison { item = (float)1, otherItem = > (double) > > > > > 1 }, > > > > > }; > > > > > > > Program program = new Program(); > > > > > > > Stopwatch watch = new Stopwatch(); > > > > > watch.Start(); > > > > > for (int i = 0; i < 10000; i++) > > > > > { > > > > > foreach (var comparison in comparisonsToMake) > > > > > { > > > > > if (!program.Compare(comparison, > createComparer)) > > > > > throw new ApplicationException("Comparison > > > > > didn't work"); > > > > > } > > > > > }; > > > > > watch.Stop(); > > > > > Console.WriteLine("All comparisons took " + > > > > > watch.ElapsedMilliseconds + "ms"); > > > > > } > > > > > > > private class Comparison > > > > > { > > > > > public object item; > > > > > public object otherItem; > > > > > } > > > > > > > private bool Compare(Comparison comparison, Func<Type, > Type, > > > > > Func<object, object, bool>> createComparer) > > > > > { > > > > > object item = comparison.item; > > > > > object otherItem = comparison.otherItem; > > > > > > > if (item == null | otherItem == null) > > > > > return item == null & otherItem == null; > > > > > > > var equalityComparer = createComparer(item.GetType(), > > > > > otherItem.GetType()); > > > > > > > return equalityComparer(item, otherItem); > > > > > } > > > > > > > } > > > > > > > On Mar 5, 11:46 pm, Ayende Rahien <[email protected]> wrote: > > > > > > > > Stopwatch.StartNew > > > > > > Please measure. > > > > > > > > On Thu, Mar 5, 2009 at 7:56 PM, webpaul <[email protected]> > wrote: > > > > > > > > > What kind of performance gain is there to what you did compared > to > > > > > > > using a TypeConverter on both objects, then a final comparison > of > > > the > > > > > > > result? Curious if you have looked at that before. > > > > > > > > > That is creating an expression for each row and compiling it > for > > > each > > > > > > > row, right? I'm guessing the main factor here is performance so > if > > > it > > > > > > > was that big of a concern I wonder if you wouldn't want to make > a > > > > > > > dictionary of them for the unique types encountered, especially > > > since > > > > > > > most rows are going to have the same columns. > > > > > > > > > I think I'm going to work up an example app with a few of these > > > > > > > methods on lots of rows, to try some of these out and see the > > > > ... > > > > read more ยป- Hide quoted text - > > > > - Show quoted text - > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Rhino Tools Dev" 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/rhino-tools-dev?hl=en -~----------~----~----~----~------~----~------~--~---
