Files
Valentin Rothberg fb31cc95a5 analyses: add README.md
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2019-07-16 14:16:16 +02:00
..
2019-07-16 14:16:16 +02:00

A set of scripts and instructions that help to analyze and debloat go-lang dependencies.

Size of packages

To analyze the size of all go packages used during the build process, pass the -work -a build flags to go build. The -a flag forces go to rebuild all packages even if they are already up-to-date (e.g., in the build cache), while the -work flag instructs go to print path of the temporary work directory used for compiling the packages. The path to the temporary work directory of go-build must be passed to go-archive-analysis.sh by setting it as an environment variable. The analysis script will then read and parse the build data and print a sorted table of the package size in bytes followed by the package name.

Running such an analysis on libpod may look as follows:

# 1) Build the podman binary with `-work -a`.

[libpod]$ BUILDFLAGS="-work -a" make podman
[...]
WORK=/tmp/go-build794287815

# 2) Set the work directory as an environment variable and call the analysis script
[libpod]$ WORK=/tmp/go-build794287815 ./dependencies/analyses/go-archive-analysis.sh | head -n10
17M github.com/containers/libpod/cmd/podman/cliconfig
13M github.com/containers/libpod/vendor/github.com/DataDog/zstd
10M github.com/containers/libpod/vendor/k8s.io/api/core/v1
3.7M net/http
3.7M github.com/containers/libpod/libpod
3.2M runtime
2.7M github.com/containers/libpod/vendor/github.com/gogo/protobuf/proto
2.5M github.com/containers/libpod/vendor/k8s.io/apimachinery/pkg/apis/meta/v1
2.3M github.com/containers/libpod/vendor/github.com/vishvananda/netlink
2.1M github.com/containers/libpod/cmd/podman/varlink

The output of the go-archive-analysis.sh script is a sorted table with the size in bytes followed by the package. The size denotes the size of the compiled package (i.e., the .a file).

Size of symbols in binary

Once the binary is compiled, we can run another set of analyses on it. The nm-symbols-analysis.sh is a wrapper around go tool nm and prints a table with size in bytes followed by the symbols name. To avoid information overload, the scripts prints only symbols from the text/code segment.

Running such an analysis on libpod may look as follows:

# 1) Compile the binary
[libpod]$ make podman
[...]

# 2) Run the script with the binary as an argument
[libpod]$ ./dependencies/nm-symbols-analysis.sh ./bin/podman | grep "containers/libpod/libpod" | head -n10
299             github.com/containers/libpod/libpod.(*BoltState).AddContainer
658             github.com/containers/libpod/libpod.(*BoltState).AddContainerToPod
2120            github.com/containers/libpod/libpod.(*BoltState).AddPod
3773            github.com/containers/libpod/libpod.(*BoltState).AddPod.func1
965             github.com/containers/libpod/libpod.(*BoltState).AddVolume
1651            github.com/containers/libpod/libpod.(*BoltState).AddVolume.func1
558             github.com/containers/libpod/libpod.(*BoltState).AllContainers
282             github.com/containers/libpod/libpod.(*BoltState).AllContainers.func1
1121            github.com/containers/libpod/libpod.(*BoltState).AllContainers.func1.1
558             github.com/containers/libpod/libpod.(*BoltState).AllPods

Running the script can help identify sources of bloat and reveal potential candidates (e.g., entire packages, types, or function) for refactoring.