digitalmars.D.learn - Struct Constructor Lazy
- Jiyan (16/16) Jul 12 2017 Hey there:)
- Biotronic (20/36) Jul 12 2017 The traditional solution is static opCall:
- Jiyan (6/27) Jul 12 2017 Hey,
- Biotronic (21/26) Jul 12 2017 Debug = no optimization. Looking at the generated assembly in a
- Jiyan (4/4) Jul 12 2017 Thank you, one last question:
- Biotronic (5/9) Jul 12 2017 That would be basically the exact equivalent - instead of passing
- Adam D. Ruppe (12/14) Jul 12 2017 That's not really true, you can have an optimized debug build.
- Adam D. Ruppe (7/8) Jul 12 2017 That's bug city... the dummy argument is better, or a named
- Adam D. Ruppe (6/12) Jul 12 2017 This is so, so irrelevant. Even if it isn't optimized out (which
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?
Jul 12 2017
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
Jul 12 2017
On Wednesday, 12 July 2017 at 11:18:08 UTC, Biotronic wrote:On Wednesday, 12 July 2017 at 11:00:54 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?[...]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
Jul 12 2017
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
Jul 12 2017
Thank you, one last question: If i declare the parameter as ref i, then there shouldnt be any overhead wouldnt it? Thanks :)
Jul 12 2017
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
Jul 12 2017
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.
Jul 12 2017
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.
Jul 12 2017
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!
Jul 12 2017