[IronPython] IPy2b5 Performance

Dino Viehland dinov at microsoft.com
Tue Oct 7 19:56:09 CEST 2008


FYI after fixing this it looks like 2.0 is about 2x faster on my machine:

10:51:23.06
C:\Product\0\Merlin\Main > ipyr x.py
0.100372393698

10:51:46.32
C:\Product\0\Merlin\Main > C:\Product\Released\IronPython-1.1\ipy.exe x.py
0.222078504391

(note I'm using time.clock() which is more precise than DateTime)

If you want to fix this locally you can replace "new DefaultPythonComparer()" in List.sort with DefaultPythonComparer.Instance. I'm planning on doing something a little more involved to avoid having this site go megamorphic in big apps but this should give you a good idea of what the change will do.  I should be able to get this in for the release candidate.  Thanks for reporting the issue!

From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Curt Hagenlocher
Sent: Tuesday, October 07, 2008 9:48 AM
To: Discussion of IronPython
Subject: Re: [IronPython] IPy2b5 Performance

A dynamic call site is the fundamental unit of dynamic dispatch in the DLR.  The first time a call (such as __cmp__) goes through the site, we have to do the work of figuring out exactly what code is going to run.  The next time the site is used, if the types of the arguments are the same then the same code is run.  So there's a lot of overhead on that first call.
On Tue, Oct 7, 2008 at 8:50 AM, Asaf Kleinbort <asaf at itstructures.com<mailto:asaf at itstructures.com>> wrote:

Thanks for the quick reply.

Today we do many 'little' sorts,  since we have a sort call in an object's __init__. However we might be able to avoid it.

I do not understand what constitutes a distinct call site. Can you give some more details on this?



From: users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com> [mailto:users-bounces at lists.ironpython.com<mailto:users-bounces at lists.ironpython.com>] On Behalf Of Curt Hagenlocher
Sent: Tuesday, October 07, 2008 5:40 PM
To: Discussion of IronPython
Subject: Re: [IronPython] IPy2b5 Performance



Every time you call sort, we create a new call site object which needs to be spun up.  So your test is really an absolute worst-case as far as performance goes.  Is it actually reflective of the circumstances under which you do sorting, where the number of sorts vastly exceeds the size of each sort?



We could reuse the sort call site instead of creating a new one for each sort, but that comes with its own problems.



Exceptions are relatively slow in the CLR, which is why it's best to use them only for actual exceptions and not for the failure path of a comparison.  In the example you give, the "best" code is probably "getattr(obj, 'prop', 0)".



On Tue, Oct 7, 2008 at 8:15 AM, Asaf Kleinbort <asaf at itstructures.com<mailto:asaf at itstructures.com>> wrote:

Hi all,

I am investigating performance problems we have when running our code using IPy2b5 (comparing to IPy 1.1.1).

Found two interesting issues:

1.       It seems that there is some bug in the 'sort' method

Running the following code:



from System import DateTime

def test():

    s = DateTime.Now

    for i in xrange(100000):

        a = [1,4,7,6,10,6]

        a.sort()

    return (DateTime.Now - s).TotalMilliseconds

            print test()



we get 3900% (!) degradation between IP1 and IPy2b5:  In IPy 1 the code runs in 390ms and in IPy2b5: 15281ms



2.This is probably already known:  there is a major difference in performance between an if/else block and a try/catch one:

        def func1(obj):

            try:

                return obj.prop

            except:

                return 0



                 def func2(obj):

            if hasattr(obj,'prop'):

                return obj.prop

            else:

                return 0



        def test(s):

                     for i in xrange(100000):

                x = func1(set())

            return (DateTime.Now -s).TotalMilliseconds



        def test2(s):

            for i in xrange(10000):

                x = func2(set())

            return (DateTime.Now -s).TotalMilliseconds



                 print test(DateTime.Now)

                 print test2(DateTime.Now)



Results for IPy1 and IPy2b5 are similar ~3000ms for 'test' and ~15ms for 'test2'. Using if/else is 200 times quicker.

In Cpython it is only 2 times quicker.



We can bypass the second issue in our code, but the first one is harder to ignore...

Are these issues already known? Any ideas?

Thanks,

Asaf





_______________________________________________
Users mailing list
Users at lists.ironpython.com<mailto:Users at lists.ironpython.com>
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



_______________________________________________
Users mailing list
Users at lists.ironpython.com<mailto:Users at lists.ironpython.com>
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20081007/b249eb50/attachment.html>


More information about the Ironpython-users mailing list