Go released Go 1.12 and Go 1.13 in 2019. Most of the changes in Go 1.13 are in the toolchain, runtime, and library implementations. Go 1.14 was released six months later.

Like its predecessors, this release retains the promise of Go 1 compatibility, with most of the updates in toolchain, runtime library performance improvements. In general, or on the basis of the existing constantly optimized commission, we expect generics have not arrived, a look at the new changes. The major updates are as follows:

  1. Module support in the Go command is now available for production
  2. Embed an interface with an overlapping set of methods
  3. Defer Performance improvements
  4. Goroutine supports asynchronous preemption
  5. Tool changes
  6. Time. Timer The Timer performance is greatly improved

Module support in the Go command is now available for production

Module support can now be used in the Go command for production use, and all users are encouraged to migrate to the Go Module for dependency management.

Embed an interface with an overlapping set of methods

Go 1.14 now allows embedding interfaces with overlapping method sets: methods from an embedded interface are allowed to have the same name and signature as methods that already exist in the (embedded) interface.

Before Go 1.14, the following definition would compile an error.

type ReadWriteCloser interface {
	io.ReadCloser
	io.WriteCloser
}
Copy the code

Defer Performance improvements

Go1.14 improves performance for most uses of defer, with almost zero overhead! Defer can already be used in performance-critical scenarios.

As for defer, some optimizations have been made in Go 1.13, and most uses of defer are 30% better than Go 1.12. Go 1.14 is even more efficient with this update!

Goroutine supports asynchronous preemption

The G-M-P model used by the scheduler. Here are some related concepts:

  • G (Goroutine) : Goroutine, created by the keyword go
  • M (Machine) : Called Machine in Go, it can be understood as a worker thread
  • P: Processor P is the intermediate layer between thread M and the Goroutine (not the CPU).

M must hold P to execute the code in G. P has its own local run queue, which is composed of runnable G. The working principle of the Go language scheduler is to select the goroutine of queue head from the queue of processor P and put it on thread M to execute. The figure above shows the relationship between thread M, processor P, and Goroutine.

Maintain the G P may be uneven, the scheduler also maintains a global G queue, when P after perform the local G task, will try to obtain from the global queue G task run (lock), when P global and local queue queue no runnable task, will try to steal other P G to the local queue in the running task (steal).

In Go 1.1, the scheduler does not support preemptive scheduling, and only relies on Goroutine to actively surrender CPU resources, which has very serious scheduling problems:

  • A single Goroutine can always run on thread without switching to another goroutine, causing starvation
  • Garbage collection pauses the entire program (stop-the-world (STW), which can take several minutes without preemption, causing the entire program to fail to work

In Go 1.12, the compiler inserts functions at a specific time and triggers preemption through function calls as entry points, thus realizing cooperative preemptive scheduling. But there are some edge cases with this scheduling approach that requires active coordination of function calls, such as the following example:

import (
	"runtime"
	"time"
)

func main(a) {
	runtime.GOMAXPROCS(1)
	go func(a) { // Create a goroutine and suspend
		for {
		}
	}()
	time.Sleep(time.Millisecond) // Main Goroutine calls sleep first
	println("OK")}Copy the code

The only P goes to the goroutine created by executing the for loop, and the main Goroutine is never scheduled again. In other words, before Go1.14, this code would never print OK. This is because the cooperative preemptive scheduling implemented by Go 1.12 does not preempt a Goroutine that has not voluntarily relinquished execution rights and does not participate in any function calls.

Go1.14 solves this problem by implementing signal-based true preemption scheduling, a very big change. The Go team reconstructs the existing logic and adds new states and fields to Goroutine to support preemption. Loops without function calls can no longer cause the scheduler to deadlock or affect the GC. It is supported on all platforms except Windows/ ARM, Darwin/ARM, JS/WASM and Plan9 /*.

As a result of preemption, programs built with Go 1.14 will receive more signals on Unix systems, including Linux and macOS systems, than programs built with earlier versions. This means that programs using packages such as Syscall or golang.org/x/sys/unix will see more slow system calls and EINTR errors. The programs will have to deal with those errors somehow, and the most likely loop is to try the system call again. For more information on this, see man 7 Signal for Linux systems or similar documentation for other systems.

Tool changes

Go mod and Go Test are some of the improvements that go 1.14 has made to the tools. Go officials definitely want developers to use the official package management tools. Go1.14 has improved many features. The go Mod has the following major improvements:

  • Incompatiable versions: If the latest version of a module contains the go.mod file, go Get will not upgrade to the incompatible major version of the module unless specifically requested or already requested. The Go List also ignores incompatible versions of this module when obtained directly from version control, but may include them if reported by an agent.
  • Go.mod file maintenance: exceptgo mod tidyThe outside go command no longer removes the require directive, which specifies the indirectly dependent version implied by the other dependencies of the main module. In addition togo mod tidyGo commands other than go no longer edit the go.mod file if the changes are cosmetic.
  • Module download: In Module mode, the GO command supports SVN repositories, and the go command now includes summaries of plain text error messages from Module agents and other HTTP servers. If the error message is a valid UTF-8 and contains graphic characters and Spaces, only the error message is displayed.

Go test-v now streams t.log output instead of output at the end of all test data.

Time. Timer The Timer performance is greatly improved

In versions prior to Go 1.10, the Go language maintained all timers using a global quadrilateral small top heap. Internal timers used by time.after, time.tick, net.conn.setDeadline, and Friends are more efficient, with fewer lock contention and fewer context switches. This is a performance improvement that does not cause any user-visible changes.

The specific improvement here, you can know by yourself, relatively complicated, the author is learning the latest implementation, the follow-up will be dedicated to this part of the content.

summary

There are many other changes to Go 1.14:

  • The change of WebAssembly
  • Reflect package changes
  • Many other important package changes (Math, HTTP, etc.)

The Go language error handling proposal received a lot of support from the community, but also a lot of opposition, conclusion: Go has abandoned the proposal! These ideas have not been fully developed, especially when considering the implementation costs of changing the language, so enumerations and immutable types have not been considered by the Go language team recently.

Go1.14 also has some planned but unfinished work. Go1.14 attempts to optimize the Page allocator to significantly reduce lock contention when GOMAXPROCS values are high. This change has a great impact, which can significantly improve Go parallelism and further improve the performance of timer. However, due to the complexity of implementation, there are some problems that can not be solved, so we have to delay until THE completion of Go1.15.

Detailed release logs of Go 1.14 can be found at golang.org/doc/go1.14.

reference

  1. Go 1.14 golang.org/doc/go1.14
  2. About Go1.14, you must want to know about the performance improvements and new features

Subscribe to the latest articles, welcome to follow my official account