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
-~----------~----~----~----~------~----~------~--~---

Reply via email to