I would say Lazy initialisation should build code that is more robust - I 
can think of few applications where that is not worth the price. So as a 
rule I agree Lazy is a good place to start unless you have a good reason 
not to. I also understood it was more idiomatic.

In terms of reading/debugging, intuitively I prefer constructors as it 
removes the need for every actor to do the check.  If you have a large 
number of methods you get a lot of repeated code. Also there will be a 
small cost to doing the check, so for performant code I would lean towards 
that.
However I did profile this once for a particular problem I was working on 
and found Lazy more performant, possibly because of the zero initialisation 
effect (not doing work twice), or maybe because the workload was spread out 
between threads and therefore the contents of the cache line was local - I 
never did get to the bottom of it. I did also wonder if Go is able to use 
the feature present in a lot of modern Caches where you can mark a line as 
Zero and the cache will never bother to fetch it from memory, saving power 
and improving latency.

It's taken me a while to come to this viewpoint as being a hardware 
engineer I'm suspicious of Go's policy of zeroing a struct at 
initialisation. "Surely", I would argue, "good software will always write a 
variable before it is read. If it reads before write then it is bad 
software and it's better to find that out sooner." I know that I am 
provably wrong on this, but still it *feels* like bad practice even if it 
isn't.
<side story>
The reason I developed such a dislike for default zero-ing is I was 
simulating the boot up of a processor, 1ms of processor time took about 30 
minutes to run. I discovered that something like 2 hours of of each 
simulation was being lost due to the boot code zeroing a block of memory 
before using it for the stack. i.e. memory that was almost guaranteed to be 
written before being read. A little more digging and overall something like 
6 hours of the 12 hour simulation was spent in memset0. 
Traumas from your youth: They cloud your thinking for the rest of your life 
:-)
</side story>

Chris
On Sunday, 4 March 2018 00:37:43 UTC, Anmol Sethi wrote:
>
> How do you guys choose between constructors and lazy initialization?
>
> For example.
>
> Struct constructors:
>
> type meow struct {
>     x http.Handler
> }
>
> func newMeow() *meow {
>     return &meow{
>         x: http.NewServeMux(),
>     }
> }
>
> func (m *meow) do() {
>     // stuff
> }
>
>
> Lazy initialization:
>
> type meow struct {
>     x http.Handler
> }
>
> func (m *meow) do() {
>     if m.x == nil {
>         m.x = http.NewServeMux()
>     }
>     // stuff
> }
>
>  

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to