Reputation: 26888
Are unused const/function/struct's method of golang package included in executable binary?
for example:
Const
which contains bunch of constants (containing SQL queries), but only few of them used in main
, would it all included in the executable binary when compiled?package Const
const (
InsertA = `insert into ...`
InsertB = `insert into ...`
UpdateA1 = `update ...` // certain column
UpdateA2 = `update ...` // other columns, different where, etc..
...
)
// in main, only some of them used/prepared
Func
which contains bunch of functions returning literals (SQL strings), but only few of them used in main
, would it all included in the executable binary when compiled?package Func
func InsertA() string { return `insert into ...` }
func InsertB() string { return `insert into ...` }
func UpdateA() string { return `Update ...` }
...
mix
, which contains bunch of functions returning/using all constants like in number 1, but only some of the functions used in main
would it all included in the executable binary when compiled?package mix
const (
insertA = `insert into ...`
insertB = `insert into ...`
updateA = `update ...`
...
)
func InsertA() string { return insertA }
func InsertB() string { return insertB }
func UpdateA() string { return updateA }
// in main, only some of the const are prepared
Struct
, which contains a lot of structs with bunch of methods (categorized SQL per table), but only some of the struct called in main
, would all constant, struct definitions, methods included in the executable binary when compiled?package Struct
const (
insertA = `insert into ...`
insertB = `insert into ...`
updateA = `update ...`
...
)
// in main only some of them prepared
type A struct {db *DB}
func (a *A) Prepare() error {}
func (a *A) InsertA(...) error {}
func (a *A) UpdateA(...) error {}
type B struct {db *DB}
func (b *B) Prepare() error {}
func (b *B) InsertB(...) error {}
// in main only some of them used (eg. only struct `A` used)
the context/case was for refactoring old codebase, so it can be better for debugging/understanding the code for new programmers (to know easily which functions/methods that modify that table by merging into one struct per table or one package per table) without sacrificing binary size, because currently all command-queries scattered in multiple binaries/packages (have to manually ctrl+F INSERT INTO tablename
or UPDATE tablename
or DELETE FROM tablename
to look which functions/methods that write/modify records on that table).
So I can decide whether it better to have one package for each table (250+) or one single package with multiple files containing empty structs of each table.
old codebase was something like this:
package hugeX
func foo() map[constQ]string {
return map[constQ]string{
insertB: `insert into...`,
updateA: `update ...`,
...
}
}
package hugeY
func foo() map[constQ]string {
return map[constQ]string{
insertA: `insert into...`,
updateB: `update ...`,
...
}
}
package foo
const (
insertB = `insert into..`
updateA = `update ...`
...
)
package bar // importing hugeX
const (
insertA = `insert into ...`
updateA = `update ...` // by something, sometimes duplicates
...
)
package baz
const (
...
)
... and so on..
Upvotes: 1
Views: 853
Reputation: 26888
after testing those and using strings
and grep
strings binaryName | grep CONSTANTSPREFIX
strings binaryName | grep CONSTANTRETURNEDBYFUNCS
strings binaryName | grep CONSTANTRETURNEDBYMETHODS
the code something like this
package a
const (
A0 = `ZAAA0` // use this on main
A1 = `ZAAA1`
A2 = `ZAAA2`
A3 = `ZAAA3`
A4 = `ZAAA4`
A5 = `ZAAA5`
A6 = `ZAAA6`
)
func B1() string { return A1 } // call this on main
func B2() string { return A2 }
func B3() string { return `ZBBB3` } // call this on main
func B4() string { return `ZBBB4` }
type C1 struct{}
func (c *C1) C3() string { return A3 } // call this on main
func (c *C1) C4() string { return A4 }
type D1 struct{}
func (c *D1) D5() string { return A5 }
func (c *D1) D6() string { return A6 }
the main:
package main
import "a"
import "fmt"
func main() {
c := a.C1{}
fmt.Println(a.A0,a.B1(),a.B3(),c.C3())
}
the result
$ go version
go version go1.15.6 linux/amd64
$ go build main.go
$ strings main | grep ZAAA
ZAAA0ZAAA1ZAAA3ZBBB3
only those that are called are included in the executable binary.
Upvotes: 2