digitalmars.D.learn - Interface vs pure abstract class - speed.
- SundayMorningRunner (10/10) May 12 2013 Hello, let's say I have the choice between using an abstract
- Diggory (11/21) May 12 2013 I would expect abstract classes to be slightly faster (certainly
- SundayMorningRunner (7/31) May 12 2013 It's ok about the difference between an interface and an abstract
- Maxim Fomin (3/13) May 12 2013 I doubt that looking from buggy compiler POV is a good idea.
- SundayMorningRunner (2/17) May 12 2013 Which is exactly what you could have done before answering ;)
- Maxim Fomin (71/89) May 12 2013 This is exactly what I *have done* before answering to get
- D-Ratiseur (3/94) May 12 2013 so take a tip: go on home.
- Sean Cavanaugh (4/12) May 13 2013 If you actually need speed you would need to use something known as the
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
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
On Sunday, 12 May 2013 at 18:00:10 UTC, Diggory wrote:On Sunday, 12 May 2013 at 17:31:22 UTC, SundayMorningRunner wrote: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...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
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
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:Which is exactly what you could have done before answering ;)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
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: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.On Sunday, 12 May 2013 at 17:31:22 UTC, SundayMorningRunner wrote:Which is exactly what you could have done before answering ;)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
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:so take a tip: go on home. so take a tip: you'll never beat the IRA.On Sunday, 12 May 2013 at 18:14:51 UTC, Maxim Fomin wrote: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.On Sunday, 12 May 2013 at 17:31:22 UTC, SundayMorningRunner wrote:Which is exactly what you could have done before answering ;)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
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.
May 13 2013