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
> > > > > > > > >>>>> > >> around is to cast one of the items as they are read 
> > > > > > > > >>>>> > >> in
> > > if
> > > > > it
> > > > > > > > >>>>> becomes
> > > > > > > > >>>>> > >> an issue so I think it's fine. Just wanted to check 
> > > > > > > > >>>>> > >> if
> > > > > that
> > > > > > > was a
> > > > > > > > >>>>> > >> desired thing or not.
>
> > > > > > > > >>>>> > >> On Feb 21, 10:43 am, Simone Busoli <
> > > > > [email protected]>
> > > > > > > > >>>>> wrote:
> > > > > > > > >>>>> > >> > That was to point out the subtlety in the .net fx. 
> > > > > > > > >>>>> > >> > I
> > > > > already
> > > > > > > > >>>>> discussed
> > > > > > > > >>>>> > >> it,
> > > > > > > > >>>>> > >> > please lookup "row equality" on the mailing list. I
> > > > > think
> > > > > > > this
> > > > > > > > >>>>> can be
> > > > > > > > >>>>> > >> > addressed in several ways, but didn't take the time
> > > to
> > > > > do it
> > > > > > > > >>>>> yet.
>
> > > > > > > > >>>>> > >> > On Sat, Feb 21, 2009 at 17:13, webpaul <
> > > > > [email protected]>
> > > > > > > > >>>>> wrote:
>
> > > > > > > > >>>>> > >> > > I looked at some recent changes and one of them
> > > was
> > > > > for
> > > > > > > > >>>>> checking row
> > > > > > > > >>>>> > >> > > equality. I noticed there was a specific test for
> > > an
> > > > > > > (int)1
> > > > > > > > >>>>> not being
> > > > > > > > >>>>> > >> > > equal to a (byte)1 - is that the desired behavior
> > > or
> > > > > was
> > > > > > > the
> > > > > > > > >>>>> test put
> > > > > > > > >>>>> > >> > > in there just to demonstrate that subtlety? I did
> > > a
> > > > > little
> > > > > > > > >>>>> test and
> > > > > > > > >>>>> > >> > > was surprised to find the below .NET framework
> > > > > behavior, I
> > > > > > > > >>>>> would have
> > > > > > > > >>>>> > >> > > thought they would be equal:
>
> > > > > > > > >>>>> > >> > > object a = (int)1;
> > > > > > > > >>>>> > >> > > object b = (byte)1;
>
> > > > > > > > >>>>> > >> > > Assert.IsFalse(a.Equals(b));
>
> > > > > > > > >>>>> > >> > > I'm
>
> ...
>
> 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