Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
July 12, 2017 Struct Constructor Lazy | ||||
---|---|---|---|---|
| ||||
Hey there:) i want to know whether the following is somehow possible: structs dont have default constructors, i know so: struct A { int field; this(int i){field = getDataFromFile("file.txt");} } A instance = A(0); Here comes my issue: when A(0) is called I would want here optimal performance, so there doesnt even need to be a value pushed on the stack (i=0), what would be like having a constructor with zero arguments (i is never used!). Im pretty new to D, can somebody tell me how i would do this? Is this(lazy int i){ ... a solution? |
July 12, 2017 Re: Struct Constructor Lazy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jiyan | On Wednesday, 12 July 2017 at 11:00:54 UTC, Jiyan wrote:
> Hey there:)
>
> i want to know whether the following is somehow possible:
> structs dont have default constructors, i know so:
>
> struct A
> {
> int field;
> this(int i){field = getDataFromFile("file.txt");}
> }
>
> A instance = A(0);
>
> Here comes my issue:
> when A(0) is called I would want here optimal performance, so there doesnt even need to be a value pushed on the stack (i=0), what would be like having a constructor with zero arguments (i is never used!).
> Im pretty new to D, can somebody tell me how i would do this?
> Is this(lazy int i){ ... a solution?
The traditional solution is static opCall:
struct A {
int field;
static A opCall() {
A result;
result.field = getDataFromFile("file.txt");
return result;
}
}
A instance = A();
I believe I've heard this is frowned upon these days, but I don't know of a better solution.
For optimal speed you might also want to skip default initialization of result, by writing A result = void;.
I would be surprised if the optimizer wasn't able to optimize away the useless parameter though - have you looked at the generated assembly?
--
Biotronic
|
July 12, 2017 Re: Struct Constructor Lazy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Biotronic | On Wednesday, 12 July 2017 at 11:18:08 UTC, Biotronic wrote:
> On Wednesday, 12 July 2017 at 11:00:54 UTC, Jiyan wrote:
>> [...]
>
> The traditional solution is static opCall:
>
> struct A {
> int field;
> static A opCall() {
> A result;
> result.field = getDataFromFile("file.txt");
> return result;
> }
> }
>
> A instance = A();
>
> I believe I've heard this is frowned upon these days, but I don't know of a better solution.
>
> For optimal speed you might also want to skip default initialization of result, by writing A result = void;.
>
> I would be surprised if the optimizer wasn't able to optimize away the useless parameter though - have you looked at the generated assembly?
>
> --
> Biotronic
Hey,
yes i did but to be honest i used dmd in debug version.
The thing about the static one, is that it creates a local object A isnt that a performance issue itself - or am i wrong - im confused actually :P?
|
July 12, 2017 Re: Struct Constructor Lazy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jiyan | On Wednesday, 12 July 2017 at 11:34:45 UTC, Jiyan wrote: > Hey, > yes i did but to be honest i used dmd in debug version. > The thing about the static one, is that it creates a local object A isnt that a performance issue itself - or am i wrong - im confused actually :P? Debug = no optimization. Looking at the generated assembly in a debug build is worthless. You raise a valid point. In a debug build, you're probably right - it will need to copy the temporary to the target. With optimizations enabled, NRVO[0] will populate the target directly, resulting in roughly the equivalent of this code: struct A { int field; static void opCall(A* p) { p.field = getDataFromFile("file.txt"); } } A a; A(&a); If the function is inlined, the whole problem is of course moot. There are probably other optimizations that can interfere with what I've described. -- Biotronic [0]: https://en.wikipedia.org/wiki/Return_value_optimization |
July 12, 2017 Re: Struct Constructor Lazy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Biotronic | Thank you, one last question: If i declare the parameter as ref i, then there shouldnt be any overhead wouldnt it? Thanks :) |
July 12, 2017 Re: Struct Constructor Lazy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jiyan | On Wednesday, 12 July 2017 at 12:02:37 UTC, Jiyan wrote:
> Thank you, one last question:
> If i declare the parameter as ref i, then there shouldnt be any overhead wouldnt it?
>
> Thanks :)
That would be basically the exact equivalent - instead of passing an int, you'll be passing a pointer.
--
Biotronic
|
July 12, 2017 Re: Struct Constructor Lazy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jiyan | On Wednesday, 12 July 2017 at 11:00:54 UTC, Jiyan wrote: > when A(0) is called I would want here optimal performance, so there doesnt even need to be a value pushed on the stack (i=0), what would be like having a constructor with zero arguments (i is never used!). This is so, so irrelevant. Even if it isn't optimized out (which it probably is), pushing a zero to the stack is so extremely cheap that you'd probably not notice it, especially compared to reading something from a file. > Im pretty new to D, can somebody tell me how i would do this? > Is this(lazy int i){ ... a solution? That's actually more expensive than just sending the zero! |
July 12, 2017 Re: Struct Constructor Lazy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Biotronic | On Wednesday, 12 July 2017 at 11:57:33 UTC, Biotronic wrote: > Debug = no optimization. That's not really true, you can have an optimized debug build. dmd's -debug, -g, and -O switches are all independent. -debug turns on blocks labeled with the `debug` switch in code. -g adds info for a debugger to read. -O turns on optimizations. You can use any combination of those. > Looking at the generated assembly in a debug build is worthless. I don't agree - looking at the generated assembly would put to rest all these questions. But before doing that, you should show that the performance is actually bad. I can't imagine sending a zero argument (whether in a register or pushed to the stack) would ever be a serious problem. |
July 12, 2017 Re: Struct Constructor Lazy | ||||
---|---|---|---|---|
| ||||
Posted in reply to Biotronic | On Wednesday, 12 July 2017 at 11:18:08 UTC, Biotronic wrote:
> The traditional solution is static opCall:
That's bug city... the dummy argument is better, or a named static factory function.
Foo foo = Foo;
Foo foo = Foo();
those are different with static opCall. It also conflicts with constructors and non-static opCall.
|
Copyright © 1999-2021 by the D Language Foundation