
The State of Go: Where we are in February 2016 - signa11
https://talks.golang.org/2016/state-of-go.slide#1
======
BenoitP
The Go runtime is really starting to look sexy. 20 ms GC pauses on 200+ GB
heaps!

I remember a thread discussing a pauseless GC on the dev mailing-list; where
Gil Tene, of Azul C4's fame, commented on having a clear policy on safepoints
from the beginning was paramount to having a good GC. It looked like the
community is very biased towards doing the fundamental things well, and
attracting the right people.

And on top of that we're get BLAS and LAPACK bindings from
[https://github.com/gonum](https://github.com/gonum)

~~~
mike_hearn
You have to be very careful about these sorts of GC statistics. Things are
often not quite what they seem and they depend a lot on the type of app you
run.

The first thing to be aware of is that with modern collectors (I have no idea
how modern Go's new collector is though), GC pause time depends on how much
live data there is in the young generation. So you can easily have enormous
heaps with very low pause times if all your objects die young and hardly ever
make it into the old generations, because then you never really need to
collect the rest of the heap at all.

Of course, outside of synthetic benchmarks, many apps don't show such pleasant
behaviour, and often GC algorithms face difficult tradeoffs that are only
really knowable by the developers. For instance, do you want low pause times,
or less CPU used by the collector (higher throughput)? It turns out that's a
fundamental tradeoff and the right answer usually depends whether your app is
a user facing server (needs low pause times) or a batch job (better to pause
for long periods but complete faster). No runtime can know that, which is why
the JVM has tons of tuning knobs. Left to its own devices you can
theoretically get away with only tweaking a single knob which is target pause
time (in G1). Set it lower and CPU usage of the collector goes up but it'll
try and pause for less time. Set it higher and the collector gets more
efficient.

Or you can just buy Zing and get rid of GC pauses entirely.

So a stat by itself like "20ms GC pauses on 200GB heaps" doesn't mean much by
itself. You can get very low pause times with huge heaps out of the JVM as
well:

    
    
      http://www.slideshare.net/HBaseCon/dev-session-7-49202969
    

but of course, you have to pay the piper somehow ... assuming non-weird heap
usage the program will run slower overall.

~~~
_ph_
The GO gc is not generational, those 20ms are for a full gc. Certainly the
details of the heap usage of the application is going to affect gc times, but
this is not the time for just a nursery collection.

~~~
mike_hearn
OK, the tradeoff they're making that I missed is that it's not a compacting
collector. So eventually your heap can fragment to the point where allocation
gets expensive or impossible. Unusual design choice.

~~~
geodel
Unlike Java Go has first class value types and memory layout can be controlled
by developers. So it leads to much less objects on heap and compact layouts
both will lead to far less fragmentation. As you can see here Go apps use
quite less memory than Java.
[https://benchmarksgame.alioth.debian.org/u64q/go.html](https://benchmarksgame.alioth.debian.org/u64q/go.html)

~~~
mike_hearn
Unfortunately it's impossible to reliably measure the memory usage of Java
that way because the JVM will happily prefer to keep allocating memory from
the OS rather than garbage collect. It makes a kind of sense: GC has a CPU
cost that gets lower the more memory is given to the heap, so if you have
spare memory lying around, may as well deploy it to make things run faster.

Of course that isn't always what you want (e.g. desktop apps) ... sometimes
you'd rather spend the CPU and minimise the heap size. The latest Java
versions on some platforms will keep track of total free system RAM and if
some other program is allocating memory quickly, it'll GC harder to reduce its
own usage and give back memory to the OS.

In the benchmarks game I suspect there aren't any other programs running at
the same time, so Java will go ahead and use all the RAM it can get. Measuring
it therefore won't give reasonable results as the heap will be full of
garbage.

Value types don't have much to do with fragmentation, if anything they make it
worse because embedding a value type into a larger container type results in
needing larger allocations that are harder to satisfy when fragmentation gets
serious. But ultimately a similar amount of data is going to end up in the
heap no matter what. Yes, you can save some pointers and some object headers,
so it'll be a bit less. But not so much that it solves fragmentation.

------
schmichael
At work (Lytics) 100% of our backend code has been in Go since the beginning
over 3 years ago, so slide #6 highlights one of the most things with nearly
every Go release:

> Changes to the language: None

[https://talks.golang.org/2016/state-of-
go.slide#6](https://talks.golang.org/2016/state-of-go.slide#6)

We generally get our entire stack upgraded to the latest release within 1-3
months with little effort. It wouldn't be much more work to be ready to
upgrade on release day, but we haven't found a reason to worry about it.

Go is such a breath of fresh air compared to past Java and Python jobs where
production was usually at least a major release version behind the latest and
there was extra effort spent getting everyone using the same implementation
(Oracle Java v OpenJDK or Ubuntu's Python v CentOS's -- there are
differences!).

Conservative releases aren't a must-have for a language, but I do appreciate
having one less operational headache to consider.

~~~
kasey_junk
Can you speak to why you were behind latest on the JVM? I can think of less
than a handful of breaking changes over the last 15 years. I'd say it was
_more_ stable than Go.

~~~
kyrra
Issues I've seen with JDK upgrades over the years (that I can think of right
now):

* when "enum" keyword was added, if you had a variable named enum you had to rename it.

* If you use any of the sun.* packages you always ask for trouble on major upgrades.

* GC changes over the years can change how your program runs (latency changes, OOM issues). This probably applies to Go as well.

~~~
schmichael
GC changes is a big one in the JVM, but not so much in Go (so far) as Go
offers basically no GC tunables.

So while your awesome CMS tweaks from JDK7 become worthless once you switch to
G1 on JDK8, with Go all you can do to optimize the GC is to create less
garbage to begin with.

Not trying to say one approach is better than the other: Go's approach is
operationally simpler but far less sophisticated than the JVM's.

~~~
voidlogic
>as Go offers basically no GC tunables.

This isn't actually true, Go has a single tunable: "GOGC"
[https://golang.org/pkg/runtime/](https://golang.org/pkg/runtime/)

~~~
schmichael
I consider that "basically no" compared to Java's daunting array of options.

------
dantillberg
The concurrent map access checks in Go1.6rc1 have already uncovered one such
bug in my code. Love it!

Oh, and I've already made use of the whitespace-stripping in text templates,
too! :)

One thing I was worried about from the focus on reducing maximum GC pause
times (i.e. latency) was that this might negatively affect GC _throughput_.
For example, maybe the pauses are shorter but there are many more of them. The
project I'm working on at the moment exercises the GC heavily but is not
concerned with latency (it's bulk data-processing), and I didn't see any
significant regression in performance/throughput from 1.5 to 1.6rc1. So, yay.

~~~
pcwalton
Aggressive GC latency improvements, like the ones Go is making, virtually
always negatively affect throughput. For example, Azul C4 has lower throughput
than HotSpot (at least per the numbers cited in the paper). There's no free
lunch in GC.

~~~
FooBarWidget
But I would argue that most people who use Go, use it to write user-facing
server apps, or at least server apps in which response time is an important
metric. I don't know anybody who uses Go to primarily write batch jobs where
throughput matters more than latency.

~~~
mike_hearn
Yeah, but that's circular - if you did want to write a high performance batch
job, maybe you wouldn't use Go because of the GC.

And hi by the way ;)

------
martijn_himself
A Golang beginner's question: do these GC improvements make Golang a suitable
language/ platform for writing games?

EDIT: I realise this is a vague question. I suppose I was wondering if the
order of magnitude GC performance in Go is likely to interfere with game loops
you might find in reasonably CPU/ GPU intensive Indie games (i.e. NOT Crysis).

~~~
espadrine
You have to ensure that the GC never makes you drop a frame. For 60Hz, that
means staying below 16.7ms.

Given that a Go 1.6 GC will still take about 4ms, you have 12.7ms to generate
a frame, which can be too limiting for some CPU-intensive games, but is
perfectly acceptable for many games.

(In Go 1.5, a GC was much more likely to make you drop a frame, as it could
easily average 40ms.)

On the other hand, there are less high-quality libraries in Go than in C++ or
in JS. That may be the most limiting factor.

~~~
mike_hearn
Interesting fact: Unreal Engine uses a GCd heap (or used to at least) for its
core game state, so that means many AAA games use GC. And you can hit 60fps
with it.

Their secret is they keep the game state heap really small. Like, 50
megabytes, maybe.

~~~
pjmlp
They still do

[https://docs.unrealengine.com/latest/INT/Programming/UnrealA...](https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Objects/Optimizations/index.html#garbagecollection)

------
ebbv
Their solution to the template whitespace thing underlines a fundamental
difference between what the Go core developers consider to be good
language/library design and what I do.

To me adding the - to the template tag {{foo -}} to get rid of whitespace on
that side of the tag is totally unintuitive and a really kludgy solution.
Sure, it's terse and being terse can be nice, but terseness to me probably
doesn't even make it into my top 10 concerns when designing a language or
library.

In my mind a lot more thought and consideration should be put into solutions
for problems that are going into core libraries. Stuffing cute hacks into the
core libraries willy nilly leads you to PHP. The consequences of which I deal
with daily.

~~~
masklinn
This change simply draws from Jinja, which has had this feature for nearly 10
years[0]. It's a simple and efficient solution to the problem of trimming
whitespace on either side of a template tag, I fail to see what is kludgy
about it (and intuitiveness is in the eye of the beholder). In my experience
it's clear, simple and doesn't make the template less readable.

> Sure, it's terse and being terse can be nice, but terseness to me probably
> doesn't even make it into my top 10 concerns when designing a language or
> library.

The whole point of this feature is to be terse, otherwise you could already
use template comment to trim formatting whitespace.

[0] [http://jinja.pocoo.org/docs/dev/templates/#whitespace-
contro...](http://jinja.pocoo.org/docs/dev/templates/#whitespace-control)

~~~
zimpenfish
Perl's Template Toolkit has had this feature since at least 2001 (and I
remember it being available before that but my googlefu is failing me right
now.)

cf
[http://www.perl.com/pub/2001/01/tt2.html](http://www.perl.com/pub/2001/01/tt2.html)

> If these tags are replaced with [%- -%] then the preceding or following
> linefeed is suppressed.

~~~
masklinn
Nice, thanks for the history lesson. Now I wonder whether Armin Ronacher got
it from there or independently reinvented it.

------
siscia
How the Go GC does comparing with the JVM one ?

~~~
vardump
JVM's gc is most likely significantly better. On the other hand golang's gc
needs to collect less objects, in _some_ cases orders of magnitude less.

If you compare a slice of structs with 1000 elements, it'll be one object (and
allocation) in golang. Equivalent array in JVM requires the array itself +
1000 Objects, 1001 allocations. In this case, golang has lot less object graph
to gc.

Of course slice of 1000 interfaces or pointers faces the same 1001 issue in
golang as well.

You could emulate same gc load cost in JVM at cost of runtime performance by
storing the objects in a byte array and [de]serialize as needed, but that's
neither idiomatic or acceptable solution most of the time.

~~~
leaveyou
Could you explain what essential things JVM does better than Go at this point
? Does it stop the world less ? Or does it do more things in parallel ? Thanks

~~~
loganekz
Although Go's GC is tunable to some extent, the open source HotSpot JVM are
already has multiple GC implementations that you can choose based on your use
case and further tune. There is also work being done in the OpenJDK project
for a GC that can collect > 100GB heaps in < 10ms [1]. There are also
alternative proprietary implementations available today that already have no
stop the world collections [2]

[1] [http://openjdk.java.net/jeps/189](http://openjdk.java.net/jeps/189) [2]
[https://www.azul.com/products/zing/](https://www.azul.com/products/zing/)

~~~
leaveyou
From this "work being done in the OpenJDK project for a GC that can collect >
100GB heaps in < 10ms" I deduce that Go 1.6 is not that bad at all and 1.7 or
1.8 could even beat that easily. [https://talks.golang.org/2016/state-of-
go.slide#37](https://talks.golang.org/2016/state-of-go.slide#37)
[https://github.com/golang/proposal/blob/master/design/12800-...](https://github.com/golang/proposal/blob/master/design/12800-sweep-
free-alloc.md)

~~~
pcwalton
Latency isn't the only concern; you also have to look at throughput. The JVM's
GC has been carefully tuned to strike a balance here.

In particular, Go's GC is not yet generational from the talks I've seen, which
is a large throughput loss compared to the GC of the JVM.

~~~
geodel
If it is carefully tuned why it needs such a big GC tuning guide and 100s of
JVM flags to tune runtime. Any Java product of consequence comes with custom
GC settings meaning they do not find default ones suitable.

[https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc...](https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/)

~~~
pcwalton
Because the JVM developers had customers who asked for the ability to tune the
GC for their particular application.

Go will receive those feature requests too. The Go developers may not be as
willing to provide so many knobs (which is a position I'm entirely sympathetic
to, don't get me wrong). But the settings always exist, regardless of whether
Google hammers in values for them or leaves them adjustable. GC is full of
tradeoffs; they're fundamental to the problem.

------
mrweasel
{{range . -}}

    
    
        <li>{{.}}</li>
    

{{end -}}

This seems like a bit of a hack to be honest. Would anything break if

{{range .}}

    
    
        <li>{{.}}</li>
    

{{end}}

worked as expected?

~~~
masklinn
It would become unusable for general-purpose text templating[0], and would
either break interspersing dynamic text ("this is {{ name }}" with name=Bob
would be rendered as "this isBob") within static text or would need a semantic
understanding of HTML.

And even then the presence or absence of whitespace in HTML does have
rendering impacts (though I don't remember one offhand — aside from linebreaks
— it's been a long time since I last hit one), so the template author must be
able to control it and importantly to keep whitespace present between static
and dynamic items.

[0] html/template is a relatively thin layer over text/template with built-in
XSS security where the original does "raw" output by default

~~~
mrweasel
I just think that a simpler solution would be to always ignore the first line
break after the range begin and end tags. I can't really see the case where
that would cause an issue, if you REALLY do need the "extra" line break just
put it inside the range.

Whitespaces shouldn't be touched, just parse them though and don't process
them.

That would make the templates look more like those of Django and Jinja2, which
most seem comfortable with.

~~~
arthurbrown
Funny that you mention Jinja.

This is actually a feature that's been in Jinja forever that I've always
wanted in Go's text/template

[http://jinja.pocoo.org/docs/dev/templates/#whitespace-
contro...](http://jinja.pocoo.org/docs/dev/templates/#whitespace-control)

------
woofiefa
I develop a lot of command line tools for Linux using shell scripting. The
scripts are getting huge and ugly, so I have been looking at Go and it seems I
can do so many things by just using the standard library and in general a big
improvement over using scripting.

However, everytime Go is discussed at HN I see many posts criticizing the
language for various reasons and this has put me off getting started learning
Go.

~~~
tshannon
I suggest just writing something in it.

A lot of the criticisms turned me off as well, but I dove in anyway.

I stopped paying attention to the criticisms when I found out how incredibly
productive I was able to be in Go.

Give it a try and make your own call on it. The cognitive overhead of jumping
into Go is so small compared to many other languages.

~~~
BuckRogers
> The cognitive overhead of jumping into Go is so small compared to many other
> languages.

I'm not using Go now, though I have tried it out years ago. Your point is
exactly why it stays on my radar for possible future use. Especially if you
consider any sort of business aspect, ramping up the help. I would strongly
consider using it for any serious backend project in a business environment
due to the performance, ease of learning and compatibility promise.

------
kasey_junk
Are there any published benchmarks around allocation times after many garbage
collection events with the golang garbage collector?

I'm wondering how it holds up without compaction and in the face of fragmented
heaps.

------
BuckRogers
> Changes to the language: None

Best part of Golang, more languages need to borrow this feature. Second best
is how relatively easy it is to get going with it.

------
oliv__
I get where we are...but where are we going?

~~~
geostyx
Go 1.7 Planning: [https://groups.google.com/forum/#!topic/golang-
dev/TerfinvPf...](https://groups.google.com/forum/#!topic/golang-
dev/TerfinvPffw)

------
ilya1
I'm wondering who is using Go in production outside US?

Noticed couple e-commerce companies and Google itself in Singapore. Few
Russian companies are doing small infra project.

Anyone else seriously investing in Golang?

~~~
thegeekpirate
It's incredibly large in China (Baidu, Qiniu). I apologize since I haven't
looked into countries specifically, but to respond to "anyone else seriously
investing in Go?", I'll paste it here for you anyways.

Walmart, Apple, Facebook, eBay, Intel, Google, Mozilla, IBM, Microsoft, Red
Hat, DigitalOcean, Zynga, Yahoo, BBC, VMware, Uber, GitHub, Getty Images,
Twitter, Stack Exchange, Docker, SpaceX, Baidu, Qiniu, Imgur, CloudFlare,
Bitbucket, Dell, Twitch, Dailymotion, bitly, Cisco, Verizon, Dropbox, Adobe,
New York Times, HP, Canonical, Cloud Foundry, 99designs, BuySellAds, CoreOS,
MongoDB, Basecamp, Rackspace, Booking, MalwareBytes, Kingsoft, Iron.io,
OpenShift, Heroku, Square, Spring, Tumblr, VMWare, Symantec, Comcast, CBS,
SendGrid, Digitally Imported, Pivotal, Couchbase, Koding, Shopify, Shutterfly,
MaxCDN, Linden Lab, SolarWinds, IMVU, EMC, Teradata, and I'm sure many more
which I'm unaware of, are all using Go to some capacity.

------
GreaterFool
How about adding a flag to the bloody compiler to allow me to compile my code
with unused bits?

I refuse to touch Go until that happens. Go is the asshole of programming
languages. It forces you to put code in deeply nested annoying directories

    
    
        vim foo.go
        vim ../../../github.com/blahblah/moreblahblah/blah.go
        sigh
    

But that I could live with. But constantly commenting the code out (which of
course leads to commenting out even more code!) is the real PITA.

All said and done it looks like a useful, if uninspired, language. Can avoid
it so may as well use it. But this nonsense has to stop!

~~~
nvader
You can use the _ signifier to mark imports as optional during development:
use

    
    
        import _ "net"
    

Make sure you don't check such lines of code in to your repo, because there is
a concrete benefit to having the language enforce this import strictness.

But the person who would check in code with unused _ imports, would probably
abuse a hypothetical "allow unused imports" flag in production. Go is probably
not for that person.

~~~
millstone
Most Go developers just use goimports. So really this "unused import" warning
is a "you forgot to push the magic fix-it button." (Why didn't it push it for
me?)

Or more to the point, if Go can figure out imports, why require them to be
explicit at all?

------
bshanks
What do people think of Go's new(ish) vendoring?

------
trungonnews
Does Go have an interactive debugger yet?

------
Eric_WVGG
yes yes, you wrote an AI that beat Fan Hui, we heard, stop bragging

------
jibalt
Oh, that Go.

------
deskamess
On FF 44.0:

\- The header is cut off

\- Slide 20 gives an error when running [c: template: redefinition of template
"list"]

\- Stable sort example does not seem to work. Gives same output as regular
sort

~~~
hamax
From the third slide:

> Most of the code examples won't run except locally and using Go 1.6.

> The playground still runs Go 1.5.

~~~
deskamess
Ah... thanks. I think I rushed past the preamble slides and missed that.

