Re: Declaring a Constructor in an Interface?

From: Dennis Myrén (dennis_at_oslokb.no)
Date: 09/15/04


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


Relevant Pages

  • Re: Declaring a Constructor in an Interface?
    ... > static void SpeedTestInterface ... > Somewhat interestingwas that the interface approach ... implementing IFoo. ... ABC: ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Why ABCs make bad Interfaces
    ... > equivalent to an Abstract Base Class (ABC). ... > because it is common practice to implement an interface using ABC's. ... To convert an object to its interface, you return a fat pointer ... The NaiveInt constructor has to set up the vtables, ...
    (comp.object)
  • Problems with extant SW for emailing
    ... Problem with Google Mail and Ubuntu ... example 1) "ABC List" in the subject line and if anybody on ABC in the ... an Internet-connected interface, then it can indeed receive mail. ... Modify settings or unsubscribe at: ...
    (Ubuntu)
  • Re: Problem with Google Mail and Ubuntu
    ... example 1) "ABC List" in the subject line and if anybody on ABC in the ... listens on port 25 and the interfaces you specify. ... an Internet-connected interface, then it can indeed receive mail. ... via the file system to the local mail ...
    (Ubuntu)
  • Why ABCs make bad Interfaces
    ... the differences between Abstract Base Classes (ABC) and Interfaces: ... because it is common practice to implement an interface using ABC's. ... to all of the neccessary vtables and lookups. ...
    (comp.object)

Loading