Go 1.20 Improves Compiler Performance and Extends Coverage Support

MMS Founder
MMS Sergio De Simone

Article originally posted on InfoQ. Visit InfoQ

The latest release of the Go language, Go 1.20, improves compiler performance, bringing it back in line with Go 1.17. Additionally, the language now supports conversion from slice to arrays and revises struct comparison.

The introduction of generics in Go 1.18 made compiler performance worse in comparison with Go 1.17. This was due mostly to changes in front-end processing, including the generics type checker and the successive parsing phase.

Go 1.18 and 1.19 saw regressions in build speed, largely due to the addition of support for generics and follow-on work. Go 1.20 improves build speeds by up to 10%, bringing it back in line with Go 1.17.

With this improvement, the process to introduce generics in Go can now be considered complete, going from an initial, functionally complete, generics implementation in Go 1.18, to runtime performance improvements in Go 1.19, to this final step to bring compile performance back in line with pre-generics Go’s.

It is worth to observe that generics may have an impact in runtime performance depending on their usage. This is more directly related to the specifics of Go’s generics implementation and is mostly noticeable when passing an interface to a generic function. The workaround for this performance hit is using pointers instead of interfaces as generic function arguments.

At the language syntax level, Go makes it easier now to convert a slice into an array. A slice in Go is a special variant of an indexed, contiguous collection that is not typed by the number of elements it contains, as Go arrays are. Converting a slice into an array, thus just requires augmenting the type associated to the slice with the number of slice items you want to use in the array. This was previously possible by applying an intermediate conversion from a slice into an array pointer into an array. Both ways are shown in the following snippet:

var aSlice = []int{ 1, 2, 3 }
var anArray = [2]int(aSlice)
var anotherArray = *(*[2]int)(aSlice) //-- old way

In Go 1.20, struct value comparison takes into account the order of the fields and stops at the first mismatch between fields, which are compared one at a time. This explicitly rules out any possibility of confusion present in the previous specification that could lead to consider that all fields should be compared, even beyond the first mismatch.

As a final note, Go 1.20 extends code coverage support to whole programs instead of just unit tests, as it was previously. This option can be enabled with the -cover flag, which instruments a build target for code coverage. Previous versions of Go required to create a dummy unit test and execute main from it to attain this same result.

Go 1.20 includes many more improvements and changes than what can be included here. Do not miss the official release notes for the full detail.

About the Author

Subscribe for MMS Newsletter

By signing up, you will receive updates about our latest information.

  • This field is for validation purposes and should be left unchanged.