November 16, 2006 Re: DMD 0.174 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stewart Gordon | Stewart Gordon wrote: > So the whole ForStatement creates a scope, and Initialize, Test, Increment and the statement body all share this scope? Yes. > This ought to be a little clearer. The way it's written at the moment ("that variable's scope extends through the end of NoScopeNonEmptyStatement") looks like a contradiction. Good point. |
November 16, 2006 Re: DMD 0.174 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | Chris Nicholson-Sauls wrote:
> Jarrett Billingsley wrote:
>
>> "Reiner Pope" <reiner.pope@REMOVE.THIS.gmail.com> wrote in message news:ejg8qd$475$1@digitaldaemon.com...
>>
>>> Jarrett Billingsley wrote:
>>
>>
>>
>>> I'm not sure if this is what you want, but here's a cast-free 'call' function:
>>>
>>> ...code...
>>
>>
>>
>> Ah! That's an alright tradeoff. I didn't actually know that you could set the .ptr and .funcptr properties of delegates; I thought they were read-only! Cool.
>>
>
> I didn't know this either... and it opens some ideas up to me... Like, perhaps one could do the following:
>
> # class Foo {
> # void bar () { ... }
> # }
> #
> # Foo[] list = ... ;
> # auto dg = &list[0].bar;
> # dg();
> # foreach (x; list[1 .. $]) {
> # dg.ptr = x;
> # dg();
> # }
>
> Might actually be slightly cheaper than a normal call in some cases, particularly of Foo and/or bar() are final. Will have to test it...
>
> -- Chris Nicholson-Sauls
Well, I tested it. And the results are... pretty neutral, really. Which is a plus in its own right, because it does at least mean one can use this trick without worry. Some exemplar output from the test program:
Repeats: 100
Iterations: 1000
List size: 500
Virtual call: 0 sec / 20 msec / 21417 usec
Manipulated delegate: 0 sec / 18 msec / 19367 usec
Repeats: 100
Iterations: 5000
List size: 500
Virtual call: 0 sec / 86 msec / 87139 usec
Manipulated delegate: 0 sec / 86 msec / 86640 usec
Repeats: 100
Iterations: 5000
List size: 25
Virtual call: 0 sec / 7 msec / 8117 usec
Manipulated delegate: 0 sec / 6 msec / 6901 usec
So, yes, there is occasionally some speedup from using the manipulated delegate, but its nothing to scream about. And it appears that, as the size of the data increases, or the number of iterations over it, the times start to drift toward each other and even out. ("Repeats" in the output is the number of times the test was run, with the results being averaged out.)
-- Chris Nicholson-Sauls
|
November 17, 2006 Re: DMD 0.174 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > Stewart Gordon wrote: >> So the whole ForStatement creates a scope, and Initialize, Test, Increment and the statement body all share this scope? > > Yes. > >> This ought to be a little clearer. The way it's written at the moment ("that variable's scope extends through the end of NoScopeNonEmptyStatement") looks like a contradiction. > > Good point. Moreover, this whole way of putting things can lead one to wonder whether variables declared in the body are reinitialized each iteration.... Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:-@ C++@ a->--- UB@ P+ L E@ W++@ N+++ o K-@ w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit. |
November 17, 2006 Re: DMD 0.174 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stewart Gordon | Stewart Gordon wrote:
> Moreover, this whole way of putting things can lead one to wonder whether variables declared in the body are reinitialized each iteration....
Why? A declaration is just like an assignment statement. It is executed when it appears. If it appears in a loop, it is executed each iteration of that loop.
|
November 17, 2006 Re: DMD 0.174 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | Chris Nicholson-Sauls wrote:
> Chris Nicholson-Sauls wrote:
>
>> Jarrett Billingsley wrote:
>>
>>> "Reiner Pope" <reiner.pope@REMOVE.THIS.gmail.com> wrote in message news:ejg8qd$475$1@digitaldaemon.com...
>>>
>>>> Jarrett Billingsley wrote:
>>>
>>>
>>>
>>>
>>>> I'm not sure if this is what you want, but here's a cast-free 'call' function:
>>>>
>>>> ...code...
>>>
>>>
>>>
>>>
>>> Ah! That's an alright tradeoff. I didn't actually know that you could set the .ptr and .funcptr properties of delegates; I thought they were read-only! Cool.
>>>
>>
>> I didn't know this either... and it opens some ideas up to me... Like, perhaps one could do the following:
>>
>> # class Foo {
>> # void bar () { ... }
>> # }
>> #
>> # Foo[] list = ... ;
>> # auto dg = &list[0].bar;
>> # dg();
>> # foreach (x; list[1 .. $]) {
>> # dg.ptr = x;
>> # dg();
>> # }
>>
>> Might actually be slightly cheaper than a normal call in some cases, particularly of Foo and/or bar() are final. Will have to test it...
>>
>> -- Chris Nicholson-Sauls
>
>
> Well, I tested it. And the results are... pretty neutral, really. Which is a plus in its own right, because it does at least mean one can use this trick without worry. Some exemplar output from the test program:
>
> Repeats: 100
> Iterations: 1000
> List size: 500
> Virtual call: 0 sec / 20 msec / 21417 usec
> Manipulated delegate: 0 sec / 18 msec / 19367 usec
>
> Repeats: 100
> Iterations: 5000
> List size: 500
> Virtual call: 0 sec / 86 msec / 87139 usec
> Manipulated delegate: 0 sec / 86 msec / 86640 usec
>
> Repeats: 100
> Iterations: 5000
> List size: 25
> Virtual call: 0 sec / 7 msec / 8117 usec
> Manipulated delegate: 0 sec / 6 msec / 6901 usec
>
> So, yes, there is occasionally some speedup from using the manipulated delegate, but its nothing to scream about. And it appears that, as the size of the data increases, or the number of iterations over it, the times start to drift toward each other and even out. ("Repeats" in the output is the number of times the test was run, with the results being averaged out.)
>
> -- Chris Nicholson-Sauls
Well... what do you know. I get back home and take a look over the test again... and find that I actually had made an error. The data wasn't getting reset between the two loops (forgot to call the reset() function... very duh moment)... which means the results for the delegate style were actually an average of its runs /plus/ the runs of the normal call! So, I fixed it... and here are a couple of sample runs:
Repeats: 100
Iterations: 1000
List size: 500
Virtual call: 0 sec / 21 msec / 21898 usec
Manipulated delegate: 0 sec / 16 msec / 17367 usec
Repeats: 100
Iterations: 5000
List size: 500
Virtual call: 0 sec / 97 msec / 98014 usec
Manipulated delegate: 0 sec / 93 msec / 94004 usec
Repeats: 100
Iterations: 5000
List size: 25
Virtual call: 0 sec / 8 msec / 9436 usec
Manipulated delegate: 0 sec / 3 msec / 4211 usec
Definitely a more significant difference than I'd previously thought! Still not a massive difference, and the results actually vary quite a bit between runs. (Sometimes by several milliseconds.) And still as the data set size or iterations grow, the times approach equality, sometimes within a couple hundred microseconds. (Every so often, the normal calls when even perform a little faster.)
I suppose, if this could cleanly and optimally be generalized into a template, it /might/ provide some benefit to those wanting to eek out as much speed as possible. Albeit with inconsistant benefits.
-- Chris Nicholson-Sauls
|
November 17, 2006 Re: DMD 0.174 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | The Phobos page is missing a link to std.traits in the left column! |
November 17, 2006 Re: DMD 0.174 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > Stewart Gordon wrote: >> Moreover, this whole way of putting things can lead one to wonder whether variables declared in the body are reinitialized each iteration.... > > Why? A declaration is just like an assignment statement. It is executed when it appears. If it appears in a loop, it is executed each iteration of that loop. True in general, but.... - in general, a declaration such as int x; doesn't look like an assignment statement - the idea of the same variable being declared multiple times in the same instance of being in the same scope is alien to many - there are also static local variables, which aren't reset each time Moreover, your claim that the _body_ of a for loop doesn't create a scope would also mean that ScopeGuardStatements and scope (fka auto) object references within the body are not processed at the end of each iteration, but saved until the end of the whole for loop. Absolutely not the behaviour I'm experiencing. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:-@ C++@ a->--- UB@ P+ L E@ W++@ N+++ o K-@ w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit. |
November 17, 2006 Re: DMD 0.174 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stewart Gordon | Stewart Gordon wrote: > Walter Bright wrote: >> Stewart Gordon wrote: >>> Moreover, this whole way of putting things can lead one to wonder whether variables declared in the body are reinitialized each iteration.... >> >> Why? A declaration is just like an assignment statement. It is executed when it appears. If it appears in a loop, it is executed each iteration of that loop. > > True in general, but.... > > - in general, a declaration such as > > int x; > > doesn't look like an assignment statement Since D has default assignment in declarations, it is one. It behaves the same way in C++ (for types that have default constructors). D isn't doing anything weird here. > - the idea of the same variable being declared multiple times in the same instance of being in the same scope is alien to many ? You cannot declare the same variable multiple times in the same scope. > - there are also static local variables, which aren't reset each time Again, this behaves just like C++, and should not be surprising. > Moreover, your claim that the _body_ of a for loop doesn't create a scope would also mean that ScopeGuardStatements and scope (fka auto) object references within the body are not processed at the end of each iteration, but saved until the end of the whole for loop. Absolutely not the behaviour I'm experiencing. The for statement itself generates a scope, not the { }. This behaves exactly like the for statement in C++. |
November 17, 2006 Re: DMD 0.174 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tomas Lindquist Olsen | Tomas Lindquist Olsen wrote:
> The Phobos page is missing a link to std.traits in the left column!
And one for std.typetuple as well.
-- Chris Nicholson-Sauls
|
November 17, 2006 Re: DMD 0.174 release | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote: > Stewart Gordon wrote: <snip> >> - the idea of the same variable being declared multiple times in the same instance of being in the same scope is alien to many > > ? You cannot declare the same variable multiple times in the same scope. What I meant is that, in order for the count variable to continue across iterations, it would imply that the control enters and leaves the scope only once for the whole for loop. And so for (int x = 0; x < 3; x++) { int y = x*x; writefln(y); } would seem equivalent to { int x = 0; int y0 = x * x; writefln(y0); x++; int y1 = x * x; writefln(y1); x++; int y2 = x * x; writefln(y2); x++; } i.e. in each instance a new y is declared, hiding the previous, but they don't go out of scope till the end of the loop. OK, so there's also the goto, which could be used to go back to before a declaration statement and execute it again. JTAI, I suppose that explains something. You're not really redeclaring it, but merely resetting its value. So while declarations may be anywhere within a function, at the internal level the placement of a declaration is merely the point at which the variable is given its initial value. >> - there are also static local variables, which aren't reset each time > > Again, this behaves just like C++, and should not be surprising. > >> Moreover, your claim that the _body_ of a for loop doesn't create a scope would also mean that ScopeGuardStatements and scope (fka auto) object references within the body are not processed at the end of each iteration, but saved until the end of the whole for loop. Absolutely not the behaviour I'm experiencing. > > The for statement itself generates a scope, not the { }. This behaves exactly like the for statement in C++. Does the flow of control enter and leave this scope only once for the whole for loop or once for each iteration? - If once for the whole loop, how would you explain the behaviour of scope guards that I'm experiencing? - If for each iteration, then how does the counter variable (if declared in the Initialize) keep hold of its value between iterations? Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:-@ C++@ a->--- UB@ P+ L E@ W++@ N+++ o K-@ w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit. |
Copyright © 1999-2021 by the D Language Foundation