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
> > > > > difference. I'll post it here within a few days.
> >
> > > > > On Mar 4, 6:23 am, Simone Busoli <[email protected]> wrote:
> > > > > > It's the .NET fx, and it's LCG, lightweight code generation.
> >
> > > > > > On Wed, Mar 4, 2009 at 10:19, webpaul <[email protected]>
> wrote:
> >
> > > > > > > Is there a framework you are using that supports this or is
> that
> > > > > > > something you guys came up with? I see a .compile in there when
> it is
> > > > > > > generating that final .Equal statement.
> >
> > > > > > > On Mar 4, 2:31 am, Simone Busoli <[email protected]>
> wrote:
> > > > > > > > I'm creating on the fly a method which performs a comparison
> of the
> > > > > two
> > > > > > > > values by coercing them to the same type.
> > > > > > > > Say you have:
> >
> > > > > > > > object a = (int)1;
> > > > > > > > object b = (byte)1;
> >
> > > > > > > > You'd get a.Equals(b) to be false, which is somewhat
> unexpected.
> >
> > > > > > > > What I'm doing is this:
> >
> > > > > > > > ((int)a).Equals((int)(byte)b), which returns true, as
> expected.
> >
> > > > > > > > There might be other ways, however.
> >
> > > > > > > > On Wed, Mar 4, 2009 at 03:40, webpaul <[email protected]>
> wrote:
> >
> > > > > > > > > Do you have a link to something that explains the general
> concept
> > > > > of
> > > > > > > > > what is going on there? I haven't ever seen anything like
> that
> > > > > before.
> >
> > > > > > > > > On Mar 3, 8:06 pm, Simone Busoli <[email protected]>
> wrote:
> > > > > > > > > > committed in rev. 2086
> >
> > > > > > > > > > On Sun, Feb 22, 2009 at 20:03, Simone Busoli <
> > > > > > > [email protected]
> > > > > > > > > >wrote:
> >
> > > > > > > > > > > Right :)  I'm not sure I can take the time in the next
> few
> > > > > days,
> > > > > > > > > though,
> > > > > > > > > > > but it's on my todo list.
> >
> > > > > > > > > > > On Sun, Feb 22, 2009 at 20:01, Ayende Rahien <
> > > > > [email protected]>
> > > > > > > > > wrote:
> >
> > > > > > > > > > >> Go for it :-)That would actually keep us consistent
> with the
> > > > > > > > > appropriate
> > > > > > > > > > >> C# behavior, which is the expected one.
> >
> > > > > > > > > > >> On Sun, Feb 22, 2009 at 1:56 PM, Simone Busoli <
> > > > > > > > > [email protected]>wrote:
> >
> > > > > > > > > > >>> What about LCG with expressions? They know how to
> compare
> > > > > each
> > > > > > > other,
> > > > > > > > > > >>> when they know who they are :)
> >
> > > > > > > > > > >>> On Sun, Feb 22, 2009 at 19:52, Ayende Rahien <
> > > > > [email protected]>
> > > > > > > > > wrote:
> >
> > > > > > > > > > >>>> Custom Comparators for the join.We can detect them
> not being
> > > > > of
> > > > > > > the
> > > > > > > > > > >>>> same type and coerce them to the bigger type
> >
> > > > > > > > > > >>>> On Sun, Feb 22, 2009 at 1:49 PM, webpaul <
> > > > > [email protected]>
> > > > > > > > > wrote:
> >
> > > > > > > > > > >>>>> How are you thinking of doing it? Casting up should
> always
> > > > > be
> > > > > > > safe,
> > > > > > > > > so
> > > > > > > > > > >>>>> you could always cast any numeric type to double or
> > > > > something
> > > > > > > like
> > > > > > > > > > >>>>> that in order to compare. That way you could
> compare 1 with
> > > > > > > 1.00
> > > > > > > > > also.
> > > > > > > > > > >>>>> Not sure if that is a perf problem or not though.
> >
> > > > > > > > > > >>>>> On Feb 22, 11:33 am, Ayende Rahien <
> [email protected]>
> > > > > wrote:
> > > > > > > > > > >>>>> > +1
> >
> > > > > > > > > > >>>>> > On Sun, Feb 22, 2009 at 11:36 AM, Simone Busoli <
> > > > > > > > > > >>>>> [email protected]>wrote:
> >
> > > > > > > > > > >>>>> > > Actually, when you're doing a join it would be
> a very
> > > > > cool
> > > > > > > > > feature
> > > > > > > > > > >>>>> to have.
> > > > > > > > > > >>>>> > > I spent quite some time wondering why the rows
> didn't
> > > > > join
> > > > > > > > > > >>>>> correctly, and it
> > > > > > > > > > >>>>> > > was because the field on which it was
> performing the
> > > > > join
> > > > > > > was
> > > > > > > > > an
> > > > > > > > > > >>>>> integer on
> > > > > > > > > > >>>>> > > one side and a byte on the other. So far, the
> solution
> > > > > has
> > > > > > > been
> > > > > > > > > to
> > > > > > > > > > >>>>> write
> > > > > > > > > > >>>>> > > tests which ensure that the two sides of the
> join have
> > > > > the
> > > > > > > same
> > > > > > > > > > >>>>> field types,
> > > > > > > > > > >>>>> > > but I would like to solve it at the RhinoETL
> level.
> >
> > > > > > > > > > >>>>> > > On Sun, Feb 22, 2009 at 03:54, webpaul <
> > > > > [email protected]
> >
> > > > > > > > > wrote:
> >
> > > > > > > > > > >>>>> > >> Ok, mission accomplished then - Makes sense
> once you
> > > > > think
> > > > > > > > > about
> > > > > > > > > > >>>>> it. I
> > > > > > > > > > >>>>> > >> certainly don't have any burning need for it
> to work
> > > > > and
> > > > > > > the
> > > > > > > > > easy
> > > > > > > > > > >>>>> work
> >
> > ...
> >
> > 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