blob: 1bb181fc7904425a66ea1ffaebf88873e0e68543 [file] [log] [blame] [view]
Dmitry Vyukov39df6ac2015-02-07 14:11:49 +03001# Compiler And Runtime Optimizations
Brad Fitzpatrickf1d499c2015-02-02 12:21:07 +01002
3This page lists optimizations done by the compilers. Note that these are not guaranteed by the language specification.
4
Josh Bleecher Snyder5afa4672015-02-04 09:50:03 -08005## Interface values
6
7### Zero-width types in interface values
Brad Fitzpatrickf1d499c2015-02-02 12:21:07 +01008
9Putting a zero-width type in an interface value doesn't allocate.
10
11* **gc:** 1.0+
12* **gccgo:** ?
13
Josh Bleecher Snyder5afa4672015-02-04 09:50:03 -080014### Word-sized value in an interface value
Brad Fitzpatrickf1d499c2015-02-02 12:21:07 +010015
16Putting a word-sized-or-less non-pointer type in an interface value doesn't allocate.
17
18* **gc:** 1.0-1.3, but *not* in 1.4+
19* **gccgo:** never
20
Oliver Beattiea63d7cd2015-03-24 14:09:51 +000021## `string` and `[]byte`
Josh Bleecher Snyder5afa4672015-02-04 09:50:03 -080022
Oliver Beattiea63d7cd2015-03-24 14:09:51 +000023### Map lookup by `[]byte`
Brad Fitzpatrickf1d499c2015-02-02 12:21:07 +010024
Oliver Beattiea63d7cd2015-03-24 14:09:51 +000025For a map `m` of type `map[string]T` and `[]byte b`, `m[string(b)]` doesn't allocate. (the temporary string copy of the byte slice isn't made)
Brad Fitzpatrickf1d499c2015-02-02 12:21:07 +010026
27* **gc:** 1.4+
28* **gccgo:** ?
29
Oliver Beattiea63d7cd2015-03-24 14:09:51 +000030### `range` over `[]byte`(s)
Brad Fitzpatrick25b2f972015-02-05 08:45:57 -080031
Oliver Beattiea63d7cd2015-03-24 14:09:51 +000032Avoiding allocating `[]byte` of a `string` when ranging over the bytes:
Brad Fitzpatrick25b2f972015-02-05 08:45:57 -080033
Oliver Beattiea63d7cd2015-03-24 14:09:51 +000034```go
Brad Fitzpatrick25b2f972015-02-05 08:45:57 -080035 s := "foo"
36 for i, c := range []byte(s) {
37 // ...
38 }
39```
40
41* **gc:** 1.5+ (CL 3790)
42* **gccgo:** ?
43
Minux Maca122f42015-02-05 01:54:53 -050044## Escape analysis and Inlining
Brad Fitzpatrickf1d499c2015-02-02 12:21:07 +010045
Minux Maca122f42015-02-05 01:54:53 -050046Use `-gcflags -m` to observe the result of escape analysis and inlining
47decisions for the gc toolchain.
48
49(TODO: explain the output of `-gcflags -m`).
50
51### Escape analysis
52
Dmitry Vyukov9b727582015-02-05 12:21:41 +030053Gc compiler does global escape analysis across function and package boundaries. However, there are lots of cases where it gives up. For example, anything assigned to any kind of indirection (`*p = ...`) is considered escaped. Other things that can inhibit analysis are: function calls, package boundaries, slice literals, subslicing and indexing, etc. Full rules are too complex to describe, so check the `-m` output.
Dmitry Vyukov8e77f6b2015-02-05 12:20:57 +030054
Minux Maca122f42015-02-05 01:54:53 -050055* **gc:** 1.0+
56* **gccgo:** not yet.
57
58### Function Inlining
59
Oliver Beattiea63d7cd2015-03-24 14:09:51 +000060Only short and simple functions are inlined. To be inlined a function must contain less than ~40 expressions and does not contain complex things like function calls, loops, labels, closures, `panic`'s, `recover`'s, `select`'s, `switch`'es, etc.
Dmitry Vyukov7da55092015-02-05 12:11:59 +030061
Minux Maca122f42015-02-05 01:54:53 -050062* **gc:** 1.0+
63* **gccgo:** -O1 and above.
Brad Fitzpatrickf1d499c2015-02-02 12:21:07 +010064
Josh Bleecher Snyder5afa4672015-02-04 09:50:03 -080065## Idioms
Brad Fitzpatrickf1d499c2015-02-02 12:21:07 +010066
Josh Bleecher Snyder5afa4672015-02-04 09:50:03 -080067### Optimized memclr
68
69For a slice or array s, loops of the form
70
71```go
72for i := range s {
73 a[i] = <zero value for element of s>
74}
75```
76
Oliver Beattiea63d7cd2015-03-24 14:09:51 +000077are converted into efficient runtime memclr calls. [Issue](https://github.com/golang/go/issues/5373) and [commit](https://golang.org/change/f03c9202c43e0abb130669852082117ca50aa9b1).
Josh Bleecher Snyder5afa4672015-02-04 09:50:03 -080078
79* **gc:** 1.5+
80* **gccgo:** ?
Dmitry Vyukov39df6ac2015-02-07 14:11:49 +030081
82## Non-scannable objects
83
Dmitry Vyukov9daa7da2015-02-07 14:12:35 +030084Garbage collector does not scan underlying buffers of slices, channels and maps when element type does not contain pointers (both key and value for maps). This allows to hold large data sets in memory without paying high price during garbage collection. For example, the following map won't visibly affect GC time:
Dmitry Vyukov39df6ac2015-02-07 14:11:49 +030085
86```go
87type Key [64]byte // SHA-512 hash
88type Value struct {
89 Name [32]byte
90 Balance uint64
91 Timestamp int64
92}
93m := make(map[Key]Value, 1e8)
94```
95
96* **gc:** 1.5+
97* **gccgo:** ?