Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
February 08, 2018 are scope guards (scope(exit, success, failure)) zero-cost abstractions? | ||||
---|---|---|---|---|
| ||||
I'm curious whether scope guards add any cost over the naive way, eg: ``` void fun(){ ... scope(success) {bar;} ... } ``` vs: ``` void fun(){ ... if(foo1){ bar; // add this before each return return; } ... bar; return; } ``` For scope(success) and scope(failure), the naive way would anyway involve try/catch statements but what about scope(exit)? Does the zero-cost exception model (zero cost being for non-thrown exceptions) guarantee us that scope(success) has 0 overhead over naive way? |
February 08, 2018 Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timothee Cour | On Thursday, 8 February 2018 at 10:09:12 UTC, Timothee Cour wrote:
> I'm curious whether scope guards add any cost over the naive way, eg:
>
> ```
> void fun(){
> ...
> scope(success) {bar;}
> ...
> }
> ```
>
> vs:
>
> ```
> void fun(){
> ...
> if(foo1){
> bar; // add this before each return
> return;
> }
> ...
> bar;
> return;
> }
> ```
>
> For scope(success) and scope(failure), the naive way would anyway
> involve try/catch statements but what about scope(exit)? Does the
> zero-cost exception model (zero cost being for non-thrown exceptions)
> guarantee us that scope(success) has 0 overhead over naive way?
Scope guards are lowered to the equivalent try/catch/finally blocks anyway.
|
February 08, 2018 Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | I know that, my question is whether it adds any runtime overhead over naive way (which is to call the "bar" finalizer before each return statement) in the case where no exception is thrown On Thu, Feb 8, 2018 at 2:44 AM, Mike Parker via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > On Thursday, 8 February 2018 at 10:09:12 UTC, Timothee Cour wrote: >> >> I'm curious whether scope guards add any cost over the naive way, eg: >> >> ``` >> void fun(){ >> ... >> scope(success) {bar;} >> ... >> } >> ``` >> >> vs: >> >> ``` >> void fun(){ >> ... >> if(foo1){ >> bar; // add this before each return >> return; >> } >> ... >> bar; >> return; >> } >> ``` >> >> For scope(success) and scope(failure), the naive way would anyway >> involve try/catch statements but what about scope(exit)? Does the >> zero-cost exception model (zero cost being for non-thrown exceptions) >> guarantee us that scope(success) has 0 overhead over naive way? > > > Scope guards are lowered to the equivalent try/catch/finally blocks anyway. |
February 08, 2018 Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions? | ||||
---|---|---|---|---|
| ||||
Attachments:
| Yes, it add, but is almost zero On Thu, Feb 8, 2018 at 12:00 PM, Timothee Cour via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > I know that, my question is whether it adds any runtime overhead over naive way (which is to call the "bar" finalizer before each return statement) in the case where no exception is thrown > > > On Thu, Feb 8, 2018 at 2:44 AM, Mike Parker via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > > On Thursday, 8 February 2018 at 10:09:12 UTC, Timothee Cour wrote: > >> > >> I'm curious whether scope guards add any cost over the naive way, eg: > >> > >> ``` > >> void fun(){ > >> ... > >> scope(success) {bar;} > >> ... > >> } > >> ``` > >> > >> vs: > >> > >> ``` > >> void fun(){ > >> ... > >> if(foo1){ > >> bar; // add this before each return > >> return; > >> } > >> ... > >> bar; > >> return; > >> } > >> ``` > >> > >> For scope(success) and scope(failure), the naive way would anyway > >> involve try/catch statements but what about scope(exit)? Does the > >> zero-cost exception model (zero cost being for non-thrown exceptions) > >> guarantee us that scope(success) has 0 overhead over naive way? > > > > > > Scope guards are lowered to the equivalent try/catch/finally blocks > anyway. > |
February 08, 2018 Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions? | ||||
---|---|---|---|---|
| ||||
Attachments:
| I mean scope(success), for scope(exit) there is no speed penalty
On Thu, Feb 8, 2018 at 12:03 PM, Daniel Kozak <kozzi11@gmail.com> wrote:
> Yes, it add, but is almost zero
>
> On Thu, Feb 8, 2018 at 12:00 PM, Timothee Cour via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote:
>
>> I know that, my question is whether it adds any runtime overhead over naive way (which is to call the "bar" finalizer before each return statement) in the case where no exception is thrown
>>
>>
>> On Thu, Feb 8, 2018 at 2:44 AM, Mike Parker via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
>> > On Thursday, 8 February 2018 at 10:09:12 UTC, Timothee Cour wrote:
>> >>
>> >> I'm curious whether scope guards add any cost over the naive way, eg:
>> >>
>> >> ```
>> >> void fun(){
>> >> ...
>> >> scope(success) {bar;}
>> >> ...
>> >> }
>> >> ```
>> >>
>> >> vs:
>> >>
>> >> ```
>> >> void fun(){
>> >> ...
>> >> if(foo1){
>> >> bar; // add this before each return
>> >> return;
>> >> }
>> >> ...
>> >> bar;
>> >> return;
>> >> }
>> >> ```
>> >>
>> >> For scope(success) and scope(failure), the naive way would anyway
>> >> involve try/catch statements but what about scope(exit)? Does the
>> >> zero-cost exception model (zero cost being for non-thrown exceptions)
>> >> guarantee us that scope(success) has 0 overhead over naive way?
>> >
>> >
>> > Scope guards are lowered to the equivalent try/catch/finally blocks
>> anyway.
>>
>
>
|
February 08, 2018 Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Thursday, 8 February 2018 at 10:44:37 UTC, Mike Parker wrote: > On Thursday, 8 February 2018 at 10:09:12 UTC, Timothee Cour wrote: >> I'm curious whether scope guards add any cost over the naive way, eg: >> >> ``` >> void fun(){ >> ... >> scope(success) {bar;} >> ... >> } >> ``` >> >> vs: >> >> ``` >> void fun(){ >> ... >> if(foo1){ >> bar; // add this before each return >> return; >> } >> ... >> bar; >> return; >> } >> ``` >> >> For scope(success) and scope(failure), the naive way would anyway >> involve try/catch statements but what about scope(exit)? Does the >> zero-cost exception model (zero cost being for non-thrown exceptions) >> guarantee us that scope(success) has 0 overhead over naive way? > > Scope guards are lowered to the equivalent try/catch/finally blocks anyway. Yes, let's look at it: ``` scope(failure) printf("%s", "error".ptr); printf("%s", "All good.".ptr); ``` 1) Lowered AST https://run.dlang.io/is/PmRfkb --- import object; import core.stdc.stdio; void main() { try { printf("%s", "All good."); } catch(Throwable __o2) { printf("%s", "error"); throw __o2; } return 0; } --- 2) Assembly (reduced to the interesting bits - see https://run.dlang.io/is/Cafgja for the full ASM) --- call printf@PLT32 jmp short L69 lea RSP,0FFFFFFF0h[RBP] mov -8[RBP],EDX mov RDI,RAX call __dmd_begin_catch@PLT32 mov -010h[RBP],RAX mov EAX,-8[RBP] cmp EAX,1 je L3F jmp short L62 L3F: lea RSI,FLAT:.rodata[00h][RIP] lea RDI,FLAT:.rodata[00h][RIP] xor EAX,EAX call printf@PLT32 mov RDI,-010h[RBP] call _d_throwdwarf@PLT32 mov RSP,RBP pop RBP ret --- |
February 08, 2018 Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Kozak | On Thursday, 8 February 2018 at 11:23:43 UTC, Daniel Kozak wrote: > I mean scope(success), for scope(exit) there is no speed penalty > > On Thu, Feb 8, 2018 at 12:03 PM, Daniel Kozak <kozzi11@gmail.com> wrote: > >> Yes, it add, but is almost zero >> >> On Thu, Feb 8, 2018 at 12:00 PM, Timothee Cour via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: >> >>> I know that, my question is whether it adds any runtime overhead over naive way (which is to call the "bar" finalizer before each return statement) in the case where no exception is thrown >>> >>> >>> On Thu, Feb 8, 2018 at 2:44 AM, Mike Parker via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: >>> > On Thursday, 8 February 2018 at 10:09:12 UTC, Timothee Cour wrote: >>> >> >>> >> I'm curious whether scope guards add any cost over the naive way, eg: >>> >> >>> >> ``` >>> >> void fun(){ >>> >> ... >>> >> scope(success) {bar;} >>> >> ... >>> >> } >>> >> ``` >>> >> >>> >> vs: >>> >> >>> >> ``` >>> >> void fun(){ >>> >> ... >>> >> if(foo1){ >>> >> bar; // add this before each return >>> >> return; >>> >> } >>> >> ... >>> >> bar; >>> >> return; >>> >> } >>> >> ``` >>> >> >>> >> For scope(success) and scope(failure), the naive way would anyway >>> >> involve try/catch statements but what about scope(exit)? Does the >>> >> zero-cost exception model (zero cost being for non-thrown exceptions) >>> >> guarantee us that scope(success) has 0 overhead over naive way? >>> > >>> > >>> > Scope guards are lowered to the equivalent try/catch/finally blocks >>> anyway. Yes, it's easy to see this when looking at the lowered AST and ASM. 1) AST https://run.dlang.io/is/KNJbnP --- import object; import core.stdc.stdio; void main() { printf("%s", "All good."); printf("%s", "FOO"); return 0; } --- 2) ASM https://run.dlang.io/is/bIVYvi --- _Dmain: push RBP mov RBP,RSP lea RSI,FLAT:.rodata[00h][RIP] lea RDI,FLAT:.rodata[00h][RIP] xor EAX,EAX call printf@PLT32 lea RSI,FLAT:.rodata[00h][RIP] lea RDI,FLAT:.rodata[00h][RIP] xor EAX,EAX call printf@PLT32 xor EAX,EAX pop RBP ret --- |
Copyright © 1999-2021 by the D Language Foundation