Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
May 12, 2013 Interface vs pure abstract class - speed. | ||||
---|---|---|---|---|
| ||||
Hello, let's say I have the choice between using an abstract class or an interface to declare a "plan", a "template" for the descendants. From the dmd compiler point of view, should I use the abstract class version (so I guess that for each method call, there will be a few MOV, in order to extract the relative address from the vmt before a CALL) or the interface version (are the CALL directly performed in this case). Are interface faster ? (to get the address used by the CALL). Thx. |
May 12, 2013 Re: Interface vs pure abstract class - speed. | ||||
---|---|---|---|---|
| ||||
Posted in reply to SundayMorningRunner | On Sunday, 12 May 2013 at 17:31:22 UTC, SundayMorningRunner wrote:
> Hello, let's say I have the choice between using an abstract class or an interface to declare a "plan", a "template" for the descendants.
>
> From the dmd compiler point of view, should I use the abstract class version (so I guess that for each method call, there will be a few MOV, in order to extract the relative address from the vmt before a CALL) or the interface version (are the CALL directly performed in this case). Are interface faster ? (to get the address used by the CALL).
>
> Thx.
I would expect abstract classes to be slightly faster (certainly they shouldn't be slower), but the difference to be insignificant compared to other factors.
Deriving from an abstract base class is a much stronger relationship than implementing an interface, so it depends on your situation. If your class is a "provider" (eg. it provides some functionality such as being able to receive some event) then an interface makes more sense. If your class is a type of something (eg. a button is a type of gui control) then inheritance makes more sense.
|
May 12, 2013 Re: Interface vs pure abstract class - speed. | ||||
---|---|---|---|---|
| ||||
Posted in reply to SundayMorningRunner | On Sunday, 12 May 2013 at 17:31:22 UTC, SundayMorningRunner wrote:
> Hello, let's say I have the choice between using an abstract class or an interface to declare a "plan", a "template" for the descendants.
> From the dmd compiler point of view, should I use the abstract class version (so I guess that for each method call, there will be a few MOV, in order to extract the relative address from the vmt before a CALL) or the interface version (are the CALL directly performed in this case). Are interface faster ? (to get the address used by the CALL).
>
> Thx.
I doubt that looking from buggy compiler POV is a good idea. Anyway you can take code and look into assembly.
|
May 12, 2013 Re: Interface vs pure abstract class - speed. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Diggory | On Sunday, 12 May 2013 at 18:00:10 UTC, Diggory wrote:
> On Sunday, 12 May 2013 at 17:31:22 UTC, SundayMorningRunner wrote:
>> Hello, let's say I have the choice between using an abstract class or an interface to declare a "plan", a "template" for the descendants.
>>
>> From the dmd compiler point of view, should I use the abstract class version (so I guess that for each method call, there will be a few MOV, in order to extract the relative address from the vmt before a CALL) or the interface version (are the CALL directly performed in this case). Are interface faster ? (to get the address used by the CALL).
>>
>> Thx.
>
> I would expect abstract classes to be slightly faster (certainly they shouldn't be slower), but the difference to be insignificant compared to other factors.
>
> Deriving from an abstract base class is a much stronger relationship than implementing an interface, so it depends on your situation. If your class is a "provider" (eg. it provides some functionality such as being able to receive some event) then an interface makes more sense. If your class is a type of something (eg. a button is a type of gui control) then inheritance makes more sense.
It's ok about the difference between an interface and an abstract
class. My question is really technical: which is the fatest:
to a method from an interface or to the overriden
method of an abstract class ? Think about a context such as audio
DSP, where a method will be called for each buffer during 2 or 3
hours without interuption, and maybe 3 or 4 times per second...
|
May 12, 2013 Re: Interface vs pure abstract class - speed. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | On Sunday, 12 May 2013 at 18:14:51 UTC, Maxim Fomin wrote:
> On Sunday, 12 May 2013 at 17:31:22 UTC, SundayMorningRunner wrote:
>> Hello, let's say I have the choice between using an abstract class or an interface to declare a "plan", a "template" for the descendants.
>> From the dmd compiler point of view, should I use the abstract class version (so I guess that for each method call, there will be a few MOV, in order to extract the relative address from the vmt before a CALL) or the interface version (are the CALL directly performed in this case). Are interface faster ? (to get the address used by the CALL).
>>
>> Thx.
>
> I doubt that looking from buggy compiler POV is a good idea. Anyway you can take code and look into assembly.
Which is exactly what you could have done before answering ;)
|
May 12, 2013 Re: Interface vs pure abstract class - speed. | ||||
---|---|---|---|---|
| ||||
Posted in reply to SundayMorningRunner | On Sunday, 12 May 2013 at 18:21:14 UTC, SundayMorningRunner wrote: > On Sunday, 12 May 2013 at 18:14:51 UTC, Maxim Fomin wrote: >> On Sunday, 12 May 2013 at 17:31:22 UTC, SundayMorningRunner wrote: >>> Hello, let's say I have the choice between using an abstract class or an interface to declare a "plan", a "template" for the descendants. >>> From the dmd compiler point of view, should I use the abstract class version (so I guess that for each method call, there will be a few MOV, in order to extract the relative address from the vmt before a CALL) or the interface version (are the CALL directly performed in this case). Are interface faster ? (to get the address used by the CALL). >>> >>> Thx. >> >> I doubt that looking from buggy compiler POV is a good idea. Anyway you can take code and look into assembly. > Which is exactly what you could have done before answering ;) This is exactly what I *have done* before answering to get correct answer for me. I see no reasons to ask such questions if you can do the test yourself. interface I { void foo(); } class A : I { void foo(){}} abstract class B { void foo() {} } class C : B {} void bar(C c, I i) { c.foo(); i.foo(); } void main() { A a = new A; a.foo(); C c = new C; c.foo(); bar(c, a); } disas _Dmain Dump of assembler code for function _Dmain: 0x0000000000419cd8 <+0>: push %rbp 0x0000000000419cd9 <+1>: mov %rsp,%rbp 0x0000000000419cdc <+4>: sub $0x10,%rsp 0x0000000000419ce0 <+8>: movabs $0x639210,%rdi 0x0000000000419cea <+18>: callq 0x41becc <_d_newclass> 0x0000000000419cef <+23>: mov %rax,-0x10(%rbp) 0x0000000000419cf3 <+27>: mov %rax,%rdi 0x0000000000419cf6 <+30>: mov (%rax),%rcx 0x0000000000419cf9 <+33>: rex.W callq *0x28(%rcx) 0x0000000000419cfd <+37>: movabs $0x639380,%rdi 0x0000000000419d07 <+47>: callq 0x41becc <_d_newclass> 0x0000000000419d0c <+52>: mov %rax,-0x8(%rbp) 0x0000000000419d10 <+56>: mov %rax,%rdi 0x0000000000419d13 <+59>: mov (%rax),%rdx 0x0000000000419d16 <+62>: rex.W callq *0x28(%rdx) 0x0000000000419d1a <+66>: mov -0x8(%rbp),%rsi 0x0000000000419d1e <+70>: cmpq $0x0,-0x10(%rbp) 0x0000000000419d23 <+75>: je 0x419d2f <_Dmain+87> 0x0000000000419d25 <+77>: mov -0x10(%rbp),%rax 0x0000000000419d29 <+81>: lea 0x10(%rax),%rdi 0x0000000000419d2d <+85>: jmp 0x419d32 <_Dmain+90> 0x0000000000419d2f <+87>: xor %rdi,%rdi ---Type <return> to continue, or q <return> to quit--- 0x0000000000419d32 <+90>: callq 0x419cb0 <_D4main3barFC4main1CC4main1IZv> 0x0000000000419d37 <+95>: xor %eax,%eax 0x0000000000419d39 <+97>: leaveq 0x0000000000419d3a <+98>: retq End of assembler dump. disas _D4main3barFC4main1CC4main1IZv Dump of assembler code for function _D4main3barFC4main1CC4main1IZv: 0x0000000000419cb0 <+0>: push %rbp 0x0000000000419cb1 <+1>: mov %rsp,%rbp 0x0000000000419cb4 <+4>: sub $0x10,%rsp 0x0000000000419cb8 <+8>: mov %rdi,-0x10(%rbp) 0x0000000000419cbc <+12>: mov %rsi,%rdi 0x0000000000419cbf <+15>: mov (%rsi),%rax 0x0000000000419cc2 <+18>: rex.W callq *0x28(%rax) 0x0000000000419cc6 <+22>: mov -0x10(%rbp),%rdi 0x0000000000419cca <+26>: mov (%rdi),%rcx 0x0000000000419ccd <+29>: rex.W callq *0x8(%rcx) 0x0000000000419cd1 <+33>: leaveq 0x0000000000419cd2 <+34>: retq End of assembler dump. |
May 12, 2013 Re: Interface vs pure abstract class - speed. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | On Sunday, 12 May 2013 at 18:45:29 UTC, Maxim Fomin wrote:
> On Sunday, 12 May 2013 at 18:21:14 UTC, SundayMorningRunner wrote:
>> On Sunday, 12 May 2013 at 18:14:51 UTC, Maxim Fomin wrote:
>>> On Sunday, 12 May 2013 at 17:31:22 UTC, SundayMorningRunner wrote:
>>>> Hello, let's say I have the choice between using an abstract class or an interface to declare a "plan", a "template" for the descendants.
>>>> From the dmd compiler point of view, should I use the abstract class version (so I guess that for each method call, there will be a few MOV, in order to extract the relative address from the vmt before a CALL) or the interface version (are the CALL directly performed in this case). Are interface faster ? (to get the address used by the CALL).
>>>>
>>>> Thx.
>>>
>>> I doubt that looking from buggy compiler POV is a good idea. Anyway you can take code and look into assembly.
>> Which is exactly what you could have done before answering ;)
>
> This is exactly what I *have done* before answering to get correct answer for me. I see no reasons to ask such questions if you can do the test yourself.
>
> interface I
> {
> void foo();
> }
>
> class A : I { void foo(){}}
>
> abstract class B { void foo() {} }
> class C : B {}
>
> void bar(C c, I i)
> {
> c.foo();
> i.foo();
> }
>
> void main()
> {
> A a = new A;
> a.foo();
> C c = new C;
> c.foo();
> bar(c, a);
> }
> disas _Dmain
> Dump of assembler code for function _Dmain:
> 0x0000000000419cd8 <+0>: push %rbp
> 0x0000000000419cd9 <+1>: mov %rsp,%rbp
> 0x0000000000419cdc <+4>: sub $0x10,%rsp
> 0x0000000000419ce0 <+8>: movabs $0x639210,%rdi
> 0x0000000000419cea <+18>: callq 0x41becc <_d_newclass>
> 0x0000000000419cef <+23>: mov %rax,-0x10(%rbp)
> 0x0000000000419cf3 <+27>: mov %rax,%rdi
> 0x0000000000419cf6 <+30>: mov (%rax),%rcx
> 0x0000000000419cf9 <+33>: rex.W callq *0x28(%rcx)
> 0x0000000000419cfd <+37>: movabs $0x639380,%rdi
> 0x0000000000419d07 <+47>: callq 0x41becc <_d_newclass>
> 0x0000000000419d0c <+52>: mov %rax,-0x8(%rbp)
> 0x0000000000419d10 <+56>: mov %rax,%rdi
> 0x0000000000419d13 <+59>: mov (%rax),%rdx
> 0x0000000000419d16 <+62>: rex.W callq *0x28(%rdx)
> 0x0000000000419d1a <+66>: mov -0x8(%rbp),%rsi
> 0x0000000000419d1e <+70>: cmpq $0x0,-0x10(%rbp)
> 0x0000000000419d23 <+75>: je 0x419d2f <_Dmain+87>
> 0x0000000000419d25 <+77>: mov -0x10(%rbp),%rax
> 0x0000000000419d29 <+81>: lea 0x10(%rax),%rdi
> 0x0000000000419d2d <+85>: jmp 0x419d32 <_Dmain+90>
> 0x0000000000419d2f <+87>: xor %rdi,%rdi
> ---Type <return> to continue, or q <return> to quit---
> 0x0000000000419d32 <+90>: callq 0x419cb0 <_D4main3barFC4main1CC4main1IZv>
> 0x0000000000419d37 <+95>: xor %eax,%eax
> 0x0000000000419d39 <+97>: leaveq
> 0x0000000000419d3a <+98>: retq
> End of assembler dump.
> disas _D4main3barFC4main1CC4main1IZv
> Dump of assembler code for function _D4main3barFC4main1CC4main1IZv:
> 0x0000000000419cb0 <+0>: push %rbp
> 0x0000000000419cb1 <+1>: mov %rsp,%rbp
> 0x0000000000419cb4 <+4>: sub $0x10,%rsp
> 0x0000000000419cb8 <+8>: mov %rdi,-0x10(%rbp)
> 0x0000000000419cbc <+12>: mov %rsi,%rdi
> 0x0000000000419cbf <+15>: mov (%rsi),%rax
> 0x0000000000419cc2 <+18>: rex.W callq *0x28(%rax)
> 0x0000000000419cc6 <+22>: mov -0x10(%rbp),%rdi
> 0x0000000000419cca <+26>: mov (%rdi),%rcx
> 0x0000000000419ccd <+29>: rex.W callq *0x8(%rcx)
> 0x0000000000419cd1 <+33>: leaveq
> 0x0000000000419cd2 <+34>: retq
> End of assembler dump.
so take a tip: go on home.
so take a tip: you'll never beat the IRA.
|
May 13, 2013 Re: Interface vs pure abstract class - speed. | ||||
---|---|---|---|---|
| ||||
Posted in reply to SundayMorningRunner | On 5/12/2013 12:31 PM, SundayMorningRunner wrote:
> Hello, let's say I have the choice between using an abstract class or an
> interface to declare a "plan", a "template" for the descendants.
>
> From the dmd compiler point of view, should I use the abstract class
> version (so I guess that for each method call, there will be a few MOV,
> in order to extract the relative address from the vmt before a CALL) or
> the interface version (are the CALL directly performed in this case).
> Are interface faster ? (to get the address used by the CALL).
>
> Thx.
If you actually need speed you would need to use something known as the curiously recurring template, and avoid using virtual (as much as possible) altogether.
|
Copyright © 1999-2021 by the D Language Foundation