golang 1.14 new features

Foreword

Go team official version 1.14 will be released in February this year. Upgrade compared to the previous, Go1.14 on the performance made a major change, but also added a lot of new features, we look together Go1.14 which gave us a pleasant surprise!

Performance improvements

1. defer performance

package main

import (
	"testing"
)

type channel chan int

func NoDefer() {
	ch1 := make(channel, 10)
	close(ch1)
}

func Defer() {
	ch2 := make(channel, 10)
	defer close(ch2)
}

func BenchmarkNoDefer(b *testing.B) {
	for i := 0; i < b.N; i++ {
		NoDefer()
	}
}

func BenchmarkDefer(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Defer()
	}
}

We were used Go1.13 version and version Go1.14 test, manage multiple versions of Go on the switch, we recommend the use gvm, very convenient. First use Go1.13 version, just command: gvm use go1.13; after running the command: go test -bench = -v, results are as follows:

goos: darwin
goarch: amd64
pkg: github.com/GuoZhaoran/myWebSites/data/goProject/defer
BenchmarkNoDefer-4   	15759076	        74.5 ns/op
BenchmarkDefer-4     	11046517	       102 ns/op
PASS
ok  	github.com/GuoZhaoran/myWebSites/data/goProject/defer	3.526s

You can see, Go1.13 version calls defer to close the performance overhead channel is still quite large, op almost worse 30ns. Switch to the go1.14: gvm use go1.14; run the command again:. Go test -bench = -v, the following results will be bright blind eyes small partners:

goos: darwin
goarch: amd64
pkg: github.com/GuoZhaoran/myWebSites/data/goProject/defer
BenchmarkNoDefer
BenchmarkNoDefer-4   	13094874	        80.3 ns/op
BenchmarkDefer
BenchmarkDefer-4     	13227424	        80.4 ns/op
PASS
ok  	github.com/GuoZhaoran/myWebSites/data/goProject/defer	2.328s

Go1.14 version defer closed channel almost 0 cost! On this improvement, the official response given is:

Go1.14 improve the performance defer most of the usage of almost 0 cost! defer already used for the scene of the high performance requirements.

goroutine support asynchronous seize

Go language scheduler performance of an iterative version with more outstanding performance, we look at GMP model used by the scheduler. First, some concepts:

  • G (Goroutine): goroutine, created by keywords go
  • M (Machine): called Machine in Go, can be understood as a worker thread
  • P (Processor): is an intermediate layer between the processor P M and Goroutines threads (not CPU)

M P must hold the code to perform the G, P has its own local run queue of the runq a, G can be run by the composition, works in Go scheduler queue processor P is selected into the head of the queue goroutine executed on a thread M, the figure shows the thread M, the relationship between the processor P and goroutine.

Here Insert Picture Description

G may be maintained for each P is not balanced, the scheduler also maintains a global queue G, when G P finished performing local tasks, task runs will attempt to acquire G (lock required) from the global queue, when P local queues and a global queue when no runnable task will attempt to steal the other P G local run queues (task stealing).

In Go1.1 version, the scheduler does not support preemptive scheduling, can only rely on goroutine initiative to the CPU resources, there is a very serious scheduling problems:

Goroutine can always occupy a separate thread to run, will not switch to other goroutine, causing hunger
garbage collection need to suspend the entire program (Stop-the-world, STW ), if not to seize the time may take several minutes, causing the entire program does not work
in Go1.12 compiler inserts function in a particular occasion, triggered by a function call to seize as the entry to achieve a collaborative preemptive scheduling. However, this function needs to take the initiative to call some edge cases with scheduling manner, for example, the following example:

package main

import (
	"runtime"
	"time"
)

func main() {
	runtime.GOMAXPROCS(1)
	
	go func() {
		for {
		}
	}()
	
	time.Sleep(time.Millisecond)
	println("OK")
}

Which create a goroutine and suspend, hibernate main goroutine priority calls, only this time P will turn to the implementation goroutine for loop created, and then main goroutine never again be scheduled. In other words before Go1.14, on top of the output code is never OK. This is because the collaborative preemptive scheduling Go1.12 not realize is that one does not give up executive power, and does not participate in any goroutine function call is preempted.

Go1.14 solved by implementing a preemptive scheduling based on real signals of the above problems, this is a very big change, Go team has been reconstructed and is a logical goroutine add new fields to support state and seize. This change makes the Go language more robust scheduler, scheduling superior performance, but there are some potential problems have not been found, is expected in the future will include more of preemption points outside the stack STW and scanning.

3 time.Timer timer performance "huge" upgrade

Published 70 original articles · won praise 1 · views 1197

Guess you like

Origin blog.csdn.net/weixin_39658118/article/details/104522509