The DefaultServeMux
part is an optimization done by Brad Fitzpatrick. I will copy and reformat the conversations between him and Matthew Dempsky from the comments on the CL:
Matthew Dempsky:
To make sure I understand, the problem is that doing
var x = newFoo()
requires newFoo()
to be called even if x is unused
Brad Fitzpatrick:
Yes, that generates:
var x *T
func init() {
x = newFoo()
}
And the linker doesn't seem to ever remove init blocks, even if they only assign to things which are otherwise only ever read. Because maybe newFoo has side-effects too?
Matthew Dempsky:
whereas
var x = &y
var y foo
skips the explicit initialization code. So if x is otherwise unused, it can be dead code eliminated along with all of type foo's related code?
Brad Fitzpatrick:
Yup
I have checked the size of the go binary compiled from the latest source code (commit 4f4a9c7fff), and I found that the change of that commit helps a lot, but var DefaultServeMux = &ServeMux{}
is a little better. See the table below:
Implementation |
size of the go binary |
var DefaultServeMux = NewServeMux() |
15870476 |
var DefaultServeMux = &defaultServeMux; var defaultServeMux ServeMux |
15864704 (-5772) |
var DefaultServeMux = &ServeMux{} |
15864696 (-5780) |
Update:
I tried to find out the difference between var DefaultServeMux = &defaultServeMux; var defaultServeMux ServeMux
and var DefaultServeMux = &ServeMux{}
at the time when that commit was created (it's back to go1.7). But I failed to compile go1.12 on my machine, so I gave up (see https://stackoverflow.com/a/76030876/1369400). What I have found is from go1.7 till now (devel go1.21-4f4a9c7fff), the two implementations are almost the same regarding the affect to the size of the go binary. Here is the result (my environment is go1.20.3 linux/amd64
and I compiled the binary with ./make.bash
):
git tag |
var DefaultServeMux = &defaultServeMux var defaultServeMux ServeMux |
var DefaultServeMux = &ServeMux{} |
delta |
go1.7 |
9966320 |
9966320 |
0 |
go1.8 |
10081258 |
10081258 |
0 |
go1.9 |
10381836 |
10381836 |
0 |
go1.10 |
11320890 |
11320890 |
0 |
go1.11 |
13032188 |
13032188 |
0 |
go1.12 |
14576719 |
14576719 |
0 |
go1.13 |
15083862 |
15083862 |
0 |
go1.14 |
15323624 |
15323624 |
0 |
go1.15 |
14272775 |
14272775 |
0 |
go1.16 |
14068974 |
14068982 |
+8 |
go1.17 |
14022237 |
14022237 |
0 |
go1.18 |
14545517 |
14545517 |
0 |
go1.19 |
15302909 |
15302909 |
0 |
go1.20 |
15579106 |
15579106 |
0 |
4f4a9c7fff |
15864704 |
15864696 |
-8 |