| The State of Go |
| Where we are in February 2016 |
| |
| Francesc Campoy |
| Gopher at Google |
| @francesc |
| campoy@golang.org |
| |
| * Time flies |
| |
| Go 1.4 is one year old (happy birthday!) |
| |
| Go 1.5 is already 6 months old! |
| |
| Go 1.6 to be released sometime in February. |
| |
| Go 1.6 Candidate Release 1 was released on January 28th |
| |
| * Notes |
| |
| The slides are available on [[https://go.dev/talks/2016/state-of-go.slide]] |
| |
| Most of the code examples won't run except locally and using Go 1.6. |
| |
| The playground still runs Go 1.5. |
| |
| * Agenda |
| |
| Changes since Go 1.5: |
| |
| - the language |
| - the standard library |
| - the runtime |
| - the tooling |
| - the community |
| |
| * Changes to the language |
| |
| * Changes to the language |
| |
| None. |
| |
| This is a feature. |
| |
| * Changes to the standard library |
| |
| * Changes to the standard library |
| |
| A couple of new things, in order of excitement. |
| |
| - net/http |
| |
| - {text,html}/template |
| |
| - sort |
| |
| Also more speed and fewer bugs. |
| |
| * net/http |
| |
| If: |
| |
| - you're using HTTPS |
| |
| - and Go 1.6 |
| |
| you're using HTTP/2! |
| |
| * HTTP/2 |
| |
| At a high level, HTTP/2: |
| |
| - is binary, instead of textual |
| - is fully multiplexed, instead of ordered and blocking |
| - can therefore use one connection for parallelism |
| - uses header compression to reduce overhead |
| - allows servers to “push” responses proactively into client caches |
| |
| .link https://http2.golang.org/gophertiles |
| |
| * text/template |
| |
| Imagine that given a slice of strings: |
| |
| []string{"one", "two", "three"} |
| |
| We want to write a template that will generate: |
| |
| <ul> |
| <li>one</li> |
| <li>two</li> |
| <li>three</li> |
| </ul> |
| |
| What template would you write? |
| |
| * text/template: first try |
| |
| Naturally, I write this: |
| |
| .play state-of-go/template/old.go /`/,/`/ |
| |
| But unfortunately it's not exactly what I want! |
| |
| * text/template: let's fix it |
| |
| We need to be careful with the line breaks. |
| |
| .play state-of-go/template/fixed.go /`/,/`/ |
| |
| This works now, but ... I don't really like my code! |
| |
| * text/template: meet {{- and -}} |
| |
| Go 1.6 brings two new delimiters: |
| |
| - `{{-` |
| - `-}}` |
| |
| Similar to `{{` and `}}`, but _all_ white space on the `-` side will be trimmed. |
| |
| The template: |
| |
| {{23 -}} |
| < |
| {{- 45}} |
| |
| generates: |
| |
| 23<45 |
| |
| * text/template: back to our problem |
| |
| We can now have: |
| |
| - the result we expected |
| - without sacrificing the readability of our templates. |
| |
| .play state-of-go/template/new.go /`/,/`/ |
| |
| * text/template: the block action |
| |
| Go 1.6 brings also a new action named `block`. |
| |
| Let's see what it is useful for. |
| |
| * Factoring out repetition in templates |
| |
| Both `<ul>` share the same structure. |
| |
| {{define "presentation"}} |
| Authors: |
| <ul> |
| {{range .Authors}} |
| <li>{{.}}</li> |
| {{end}} |
| </ul> |
| |
| Topics: |
| <ul> |
| {{range .Topics}} |
| <li>{{.}}</li> |
| {{end}} |
| </ul> |
| {{end}} |
| |
| Templates can be used to avoid repetition. |
| |
| * Factoring out repetition with templates (cont.) |
| |
| We can define a new template: |
| |
| .code state-of-go/template/define.go /define "list"/,/^{{end}}/ |
| |
| And use it where needed: |
| |
| .code state-of-go/template/define.go /define "presentation"/,/^{{end}}/ |
| |
| * Factoring out repetition with templates (cont.) |
| |
| We can parse that template and execute it. |
| |
| .play state-of-go/template/define.go /func main/,/^}/ |
| |
| * Template redefinition |
| |
| We made also our template easier to reuse, as we can redefine `list`. |
| |
| .play state-of-go/template/redefine.go /func main/,/^}/ |
| |
| * Meet the block action |
| |
| The `block` action defines and executes a template in place. |
| |
| .code state-of-go/template/blocks.go /define/,/`/ |
| |
| That template defined by `block` can be: |
| |
| - referenced later by the same template, |
| - redefined with `define`. |
| |
| * Why do we need it? |
| |
| It is more compact when |
| |
| - we're not factoring out repetition, |
| - but we need to provide an extension point. |
| |
| We can make the following template more compact with `block`. |
| |
| {{define "content" .}} |
| <h1>{{.Heading}}<h1> |
| <p>{{.Content}}</p> |
| {{end}} |
| |
| {{define "page"}} |
| <title>{{.Title}}</title> |
| <body> |
| {{template "content" .}} |
| </body> |
| {{end}} |
| |
| * Why do we need it? (cont.) |
| |
| We can make the following template more compact with `block`. |
| |
| {{define "page"}} |
| <title>{{.Title}}</title> |
| <body> |
| {{block "content" .}} |
| <h1>{{.Heading}}<h1> |
| <p>{{.Content}}</p> |
| {{end}} |
| </body> |
| {{end}} |
| |
| And still easily redefine `content`. |
| |
| * sort.Sort is faster |
| |
| `Sort` sorts your data by calling `Less`, `Swap`, and `Len`. |
| |
| We reduced the number of comparisons and swaps by about 10%. |
| |
| Sort `[]int` with Go 1.5 |
| |
| BenchmarkSort_1-4 20000000 67.2 ns/op |
| BenchmarkSort_10-4 10000000 227 ns/op |
| BenchmarkSort_100-4 500000 3863 ns/op |
| BenchmarkSort_1000-4 30000 52189 ns/op |
| |
| Sort `[]int` with Go 1.6 |
| |
| BenchmarkSort_1-4 20000000 64.7 ns/op |
| BenchmarkSort_10-4 10000000 137 ns/op |
| BenchmarkSort_100-4 500000 2849 ns/op |
| BenchmarkSort_1000-4 30000 46949 ns/op |
| |
| * sort.Sort is faster - plot |
| |
| .image state-of-go/img/bench-sort.png _ 800 |
| |
| * Sort order and sort.Stable |
| |
| Reminder: sort.Sort is not a _stable_ sort. |
| |
| .play state-of-go/sort/unstable.go /byLength/, |
| |
| Use `sort.Stable`: |
| |
| .play state-of-go/sort/stable.go /func main/, |
| |
| * Minor changes |
| |
| .image state-of-go/img/minorchanges.png _ 900 |
| .caption too many to discuss: find them [[https://golang.org/doc/go1.6#minor_library_changes][here]] |
| |
| * Let's just discuss one |
| |
| `time.Parse` is smarter! |
| |
| .play state-of-go/time/time.go /func main/,/^}/ |
| |
| |
| * Changes to the runtime |
| |
| * Detection of concurrent map accesses |
| |
| Detection of unsafe concurrent access to maps. |
| |
| .play state-of-go/runtime/crash.go /const/,/Wait\(\)/ |
| |
| Outputs: |
| |
| fatal error: concurrent map read and map write |
| fatal error: concurrent map writes |
| |
| * Does it make it slower? |
| |
| No! |
| |
| Let's benchmark it - with a correct solution. |
| |
| .code state-of-go/runtime/good/good.go /func count/,/^}/ |
| |
| * Benchmark results |
| |
| Go 1.4 - GOMAXPROCS = 4 |
| |
| BenchmarkCount_1 1000000 1862 ns/op |
| BenchmarkCount_10 100000 21214 ns/op |
| BenchmarkCount_100 1000 1602507 ns/op |
| BenchmarkCount_1000 10 141712948 ns/op |
| |
| Go 1.5 - GOMAXPROCS = 4 |
| |
| BenchmarkCount_1-4 2000000 867 ns/op |
| BenchmarkCount_10-4 200000 6909 ns/op |
| BenchmarkCount_100-4 1000 1025092 ns/op |
| BenchmarkCount_1000-4 20 94093719 ns/op |
| |
| Go 1.6 - GOMAXPROCS = 4 |
| |
| BenchmarkCount_1-4 2000000 750 ns/op |
| BenchmarkCount_10-4 200000 6582 ns/op |
| BenchmarkCount_100-4 2000 1113790 ns/op |
| BenchmarkCount_1000-4 20 87998054 ns/op |
| |
| * Benchmark results plot |
| |
| .image state-of-go/img/bench4.png _ 800 |
| |
| * Benchmark results |
| |
| Go 1.4 - GOMAXPROCS = 1 |
| |
| BenchmarkCount_1 100000 1370 ns/op |
| BenchmarkCount_10 20000 8622 ns/op |
| BenchmarkCount_100 500 362725 ns/op |
| BenchmarkCount_1000 50 31378803 ns/op |
| |
| Go 1.5 - GOMAXPROCS = 1 |
| |
| BenchmarkCount_1-4 2000000 776 ns/op |
| BenchmarkCount_10-4 200000 6288 ns/op |
| BenchmarkCount_100-4 3000 345037 ns/op |
| BenchmarkCount_1000-4 50 31751625 ns/op |
| |
| Go 1.6 - GOMAXPROCS = 1 |
| |
| BenchmarkCount_1-4 2000000 767 ns/op |
| BenchmarkCount_10-4 200000 6041 ns/op |
| BenchmarkCount_100-4 5000 329328 ns/op |
| BenchmarkCount_1000-4 50 30176034 ns/op |
| |
| * Benchmark results plot |
| |
| .image state-of-go/img/bench1.png _ 800 |
| |
| * Garbage Collector in Go 1.5 |
| |
| At [[https://www.youtube.com/watch?v=aiv1JOfMjm0][GopherCon 2015 Rick Hudson gave a presentation]] about the Go 1.5 low latency collector |
| |
| .image state-of-go/img/gc345.png 500 _ |
| |
| * Garbage Collector in Go 1.6 |
| |
| At [[http://www.infoq.com/presentations/go-gc-performance][QCon SF in November Rick Hudson]] gave an updated presentation which showed this comparison of Go 1.5 to the upcoming Go 1.6 |
| |
| .image state-of-go/img/gc56.png 400 _ |
| |
| _Yes,_that_is_gigabytes_on_the_X_axis_ |
| |
| * Garbage Collector on tip |
| |
| Right now it's even better! |
| |
| .image state-of-go/img/gcgotip.png _ 600 |
| |
| * People loved it with Go 1.5 |
| |
| .image state-of-go/img/twitter1.png _ 550 |
| .caption [[https://twitter.com/brianhatfield/status/634166123605331968][original tweet]] |
| |
| * People love it even more with Go 1.6 |
| |
| .image state-of-go/img/twitter2.png _ 600 |
| .caption [[https://twitter.com/brianhatfield/status/692778741567721473][original tweet]] |
| |
| * Oops |
| |
| .image state-of-go/img/twitter3.png _ 600 |
| .caption [[https://twitter.com/bradfitz/status/692787593558118400][original tweet]] and [[https://www.youtube.com/watch?v=CduA0TULnow&t=1m29s][video]] |
| |
| * New ports |
| |
| Experimental ports to Linux on 64-bit MIPS (linux/mips64 and linux/mips64le). |
| |
| Experimental port to Android on 32-bit x86 (android/386). |
| |
| On Linux on little-endian 64-bit PowerPC (linux/ppc64le), Go 1.6 now supports cgo with external linking and is roughly feature complete. |
| |
| On NaCl, Go 1.5 required SDK version pepper-41. Go 1.6 adds support for later SDK versions. |
| |
| * Changes to the tooling |
| |
| * The cgo tool |
| |
| Go is garbage collected, can C and Go share memory? |
| |
| In short: |
| |
| - Go can pass a pointer to C |
| - the referenced memory can't have pointers to Go allocated memory |
| - C can't keep pointers to the memory after the call returns |
| |
| In more detail: |
| |
| - the `cgo` [[https://tip.golang.org/cmd/cgo/#hdr-Passing_pointers][docs]]. |
| |
| This is checked by the runtime at execution. |
| |
| You could disable the checks, but you probably shouldn't. |
| |
| * Sharing pointers between Go and C |
| |
| .code state-of-go/cgo/main.go |
| |
| Outputs: |
| |
| panic: runtime error: cgo argument has Go pointer to Go pointer |
| |
| * The go tool |
| |
| GO15VENDOREXPERIMENT is now enabled by default. |
| |
| How does it work? |
| |
| /home/user/gocode/ |
| src/ |
| server-one/ |
| main.go (import "github.com/gorilla/mux") |
| server-two/ |
| main.go (import "github.com/gorilla/mux") |
| vendor/ |
| github.com/ |
| gorilla/ |
| mux/ |
| ... |
| |
| `server-one` uses the `mux` package in `$GOPATH/src/github.com/gorilla/mux`. |
| |
| `server-two` uses the `mux` package in `vendor`. |
| |
| * Vendoring demo |
| |
| * go doc |
| |
| Go 1.5 added the possibility of searching by name |
| |
| go doc math Pi |
| |
| Go 1.6 defines priority of packages with import paths with less elements. |
| |
| Non vendored packages appear first. |
| |
| * go vet |
| |
| Go vet warns if the code prints a function instead of its result. |
| |
| .play state-of-go/govet/main.go |
| |
| `go`vet` output: |
| |
| main.go:8: arg foo in Println call is a function value, not a function call |
| |
| The warning can be removed using `%p` in the format string. |
| |
| * The community |
| |
| * The community |
| |
| Code of Conduct announced on November 24th 2015 |
| |
| Go meetups: |
| |
| - [[http://go-meetups.appspot.com]] |
| |
| Women Who Go - 7 chapters already! |
| |
| - [[http://www.womenwhogo.org]] |
| |
| * Conferences: |
| |
| - [[http://gophergala.com/][GopherGala]] Jan 22-24th (judging proposals now) |
| - [[https://fosdem.org/2016/][FOSDEM]] Right here, right now. Hello! |
| - [[http://gophercon.ae][GopherCon Dubai]], Feb 23rd |
| - [[http://www.gophercon.in/][GopherCon India]], Feb 19-20th |
| - [[https://gophercon.com/][Gophercon Denver]], Jul 11-13th |
| - [[http://2016.dotgo.eu/][dotGo]], Nov 9th |
| |
| * Go 1.6 release party, February 17th |
| |
| Go 1.6 ships soon! |
| |
| Go meetups are organising to hold a [[https://github.com/golang/go/wiki/Go-1.6-release-party][release party]] on the 17th of February. |
| |
| .image state-of-go/img/party-gopher.png _ 300 |
| .caption Join the party!!! |