Re: Declaring a Constructor in an Interface?
From: Dennis Myrén (dennis_at_oslokb.no)
Date: 09/15/04
- Next message: Nak: "Re: Decompiler.NET reverse engineers your CLS compliant code"
- Previous message: Dante: "Re: iframe"
- In reply to: Ian Griffiths [C# MVP]: "Re: Declaring a Constructor in an Interface?"
- Next in thread: Ian Griffiths [C# MVP]: "Re: Declaring a Constructor in an Interface?"
- Reply: Ian Griffiths [C# MVP]: "Re: Declaring a Constructor in an Interface?"
- Messages sorted by: [ date ] [ thread ]
Date: Wed, 15 Sep 2004 16:50:33 +0200
Thanks for the help once again mr. Griffiths.
Yes, I also noticed the strange differences when running your test
and comparing the results to those that you got.
>1) Is that definitely the results from
>the code I posted with no mods at all?
Yes, it is! Very strange indeed.
>2) Did you let the test run to completion? The first set of results will
>probably be bogus due to JIT compilation transient timing issues. You want
>to ignore the first three results and look at the rest it prints out.
Yes, i looped five times, and i also repeated the execution of the program 3
times.
I will run once again now, and paste the exact output at the end of this
post
(using your code, absolutely unmodified).
>3) What version of the .NET framework are you running this on?
I am running .NET Framework v1.1.4322.
>4) Are you running in the debugger?
Yes, i am running in debug mode from Visual Studio .NET Version 7.1.3088.
INFORMATION ABOUT MY SYSTEM:
Acer Laptop Machine, Intel Pentium M Processor 1700 MHz, 512 MB of RAM
running Windows XP Professional Version 2002 Service Pack 1
EXACT PROGRAM EXECUTION OUTPUT:
Non-virtual: 111,6 million calls per second
ABC: 108,73 million calls per second
Interface: 98,14 million calls per second
Non-virtual: 110,41 million calls per second
ABC: 110,83 million calls per second
Interface: 96,91 million calls per second
Non-virtual: 106,86 million calls per second
ABC: 110,19 million calls per second
Interface: 97,58 million calls per second
Non-virtual: 110,26 million calls per second
ABC: 108,95 million calls per second
Interface: 98,58 million calls per second
Non-virtual: 108,77 million calls per second
ABC: 102,65 million calls per second
Interface: 91,38 million calls per second
Hmm what is wrong with my system.
--
Regards,
Dennis JD Myrén
Oslo Kodebureau
"Ian Griffiths [C# MVP]" <ian-interact-sw@nospam.nospam> wrote in message
news:ewkoz7ymEHA.3684@TK2MSFTNGP12.phx.gbl...
> Dennis Myrén wrote:
> >
> > Therefore, i decided to modify your test program slightly
> > to better match my current project.
> >
> > I changed:
> > static void SpeedTestInterface(IFoo obj)
> > into:
> > static void SpeedTestInterface(InterfaceImpl obj)
> > and also:
> > static void SpeedTestABC(ABC obj)
> > into:
> > static void SpeedTestABC(ConcreteDerived obj)
> >
> > Somewhat interesting(to me anyway) was that the interface approach
> > went a lot faster.
>
> Have a look at the IL. Before your change, the way that
SpeedTestInterface
> calls the method is:
>
> callvirt instance void IFoo::SayHello()
>
> but after your change, it looks like this:
>
> callvirt instance void InterfaceImpl::SayHello()
>
> And don't be misled by that 'callvirt' - the 'virt' part doesn't mean what
> you might thing. The thing that determines whether virtual, interface, or
> basic method dispatch gets used is the nature of the target method.
>
> In the first case, it's calling IFoo.SayHello. And since that's an
interface
> method, it will be using interface-style dispatch.
>
> But in the second case, notice that it has completely ignored the
interface.
> (Indeed, you can modify the InterfaceImpl class so that it no longer
claims
> to implement IFoo without changing the behaviour.) The compiler has done
> this because your program no longer relies on the InterfaceImpl class
> implementing IFoo. It's just calling the public SayHello method directly.
> This is why you get the same performance as you would with any other
direct
> method call - you really aren't using interfaces in this case. You're
> calling a public method. It so happens that the public method is also
> available via an interface, but you're not exploiting that here. (As is
> easily proved by the fact that removing the interface from the list that
> InterfaceImpl implements doesn't stop your version of the program from
> working.)
>
> This only works because you made SayHello public. So it's not just there
to
> implement the IFoo interface, it's also a part of InterfaceImpl's public
> face in its own right. It would be different if you had done this:
>
> public class InterfaceImpl : IFoo
> {
> void IFoo.SayHello() { }
> }
>
> This C# syntax says that this method is the implementation of
IFoo.SayHello,
> but is *not* part of the class's public API. You'll find that if you do
> this, your modified version of the test won't work. You'll have to go back
> to what I wrote, and it will of course run slower again.
>
>
>
> >This is my most average results running your test with no modification:
> >Non-virtual: 103,63 million calls per second
> >ABC: 104,47 million calls per second
> >Interface: 81,98 million calls per second
>
> Now that's interesting. Are these really the results you got with the
code
> exactly as I posted it?
>
> It's interesting because you're getting very different results from me.
> (Obviously the results are different partly because we have different
> hardware. But what's interesting is the relative differences beween each
> type of call.) I get this:
>
> Non-virtual: 510.16 million calls per second
> ABC: 170.31 million calls per second
> Interface: 155.36 million calls per second
>
> So my non-virtual calls are way faster than the other two. You're finding
> the non-virtual runs about the same speed as the ABC calls, which is
> completely different from what I got. (So it looks almost as though your
> non-virtual case has been slowed down to run at the same speed as the
> virtual call.)
>
> So, four questions:
>
> 1) Is that definitely the results from the code I posted with no mods at
> all?
> 2) Did you let the test run to completion? The first set of results will
> probably be bogus due to JIT compilation transient timing issues. You
want
> to ignore the first three results and look at the rest it prints out.
> 3) What version of the .NET framework are you running this on?
> 4) Are you running in the debugger?
>
> > And this is my most average results running your test with those
> > modifications:
> > Non-virtual: 104,16 million calls per second
> > ABC: 103,93 million calls per second
> > Interface: 102,7 million calls per second
> >
> > Is there a logical explanation for that speed enhancement?
>
> Yes - the case labelled as "Interface" is no longer really using
interfaces
> for the reasons described above. But again, your figures look different
from
> mine. I get this kind of thing with your modifications:
>
> Non-virtual: 512.36 million calls per second
> ABC: 172.32 million calls per second
> Interface: 515.27 million calls per second
>
> So these are figures that makes sense to me, because with your
modifications
> to the test, the so-called 'Interface' case isn't using interfaces any
more.
> It's making a direct call on a method which happens also to be available
via
> an interface which the code is choosing not to use. So as you'd expect,
> it's running at about the same speed as the other 'non-virtual' case.
(Give
> or take a few percent, which will just be experimental error.)
>
> What I don't understand is why in both your 'before' and 'after' cases,
the
> ABC case runs roughly as fast as the direct call. I wouldn't expect it
to,
> and on my system it definitely doesn't! So I'm trying to understand
what's
> different about your setup and mine.
>
> If you are running in the debugger, try running outside instead. I just
> compiled and ran it from the command line.
>
>
> --
> Ian Griffiths - http://www.interact-sw.co.uk/iangblog/
> DevelopMentor - http://www.develop.com/
>
>
- Next message: Nak: "Re: Decompiler.NET reverse engineers your CLS compliant code"
- Previous message: Dante: "Re: iframe"
- In reply to: Ian Griffiths [C# MVP]: "Re: Declaring a Constructor in an Interface?"
- Next in thread: Ian Griffiths [C# MVP]: "Re: Declaring a Constructor in an Interface?"
- Reply: Ian Griffiths [C# MVP]: "Re: Declaring a Constructor in an Interface?"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|