36 comments

[ 4.8 ms ] story [ 80.8 ms ] thread
God of Speed Dmitry Vyukov.
Dmitry is in my personal programmer hall of fame.
Ditto, the guy is a real software engineer.
I agree.

But it has always bothered me how he declares pointers! :-)

(stack[pointer] s, node[pointer] n)

Instead of

(stack [pointer]s, node [pointer]n)

Am I picky? :-)

[pointer] is the * just trying to avoid the italics conversion of HN.

I remember I was going back and forth between the two over the years, and I had to keep looking up which was my "latest" preferred style.

I eventually came to the following,

(stack [pointer] s, node [pointer] n)

Since it's symmetrical, it's easy to remember.

Luckily, I've been using Go and gofmt (goimports, specifically) the last 2 years so this is no longer an issue.

> GC scanning and marking phase is 10-20% faster for programs with large number of small objects.

Which is most programs. Hurray, changes in good direction.

In Go you avoid allocations for small values and use the stack.
(comment deleted)
Do you do that explicitly or is at a compiler optimization?
Both. If you deal with a value type (struct or primitive) and never take the address of it, it can't exist anywhere besides the current stack, value types are copied if you return it out of a function or call another function with it.

For reference types, they do have escape analysis, not sure how one would compare it to another language.

To be fair, we do that to avoid GC slowdown issues. If the GC improves to the point where that's no longer an issue, we don't have to do that anymore :)
A 30% improvement is nice but nowhere near enough to change programming best practices in go.

A significant algorithmic change in the GC, like a generational compacting GC or something along those lines, would have to be made to alter go programming strategies.

No mention of a generational collector. The word concurrent is in there though.
In 1.3 the GC is concurrent mark and sweep
I thought generational and mark/sweep were orthogonal. That is, can't generational still be mark and sweep? You just don't mark and sweep the entire reference set?
Generational collectors can pick any strategy for each of their generations. What to pick depends on language, and what characteristics you want to get easily.
Recounting for tenured generations would be awesome!
Why mod someone down for asking about a generational GC?
My comment was a little flip, I know, I should have asked a more friendly question. I'm wondering why it hasn't been discussed (as far as I can tell). Java has had it for ages, Ruby will have it in 2.1 and Python appears to have it as well [1]. Isn't Generational GC feasible in Go for some reason?

[1] https://docs.python.org/2/library/gc.html

Edit: Here is a discussion of gc in go. Go has only just gotten a precise collector, which is a requirement of a generational gc, to allow moving pointers.

https://groups.google.com/forum/#!topic/golang-nuts/fiOs3mGH...

FYI: Ruby 2.1 has been released for some time now.
I've heard talk of plans for a generational, moving GC in future. It's just not something that can be implemented overnight, especially in a language with internal pointers (which Java, Ruby and Python lack).
(comment deleted)
(comment deleted)
Slightly off topic, but is there a good (i.e., fast and easy to use) modern retargetable GC for language prototyping/implementation? I've been looking for something like this for a while, but it seems everyone rolls their own.
For prototyping could you use malloc without free? I have been rolling my own GC and wish that I would have left this until later.
Basic mark & sweep is simple to understand and implement. See e.g. https://code.google.com/p/tinypy/source/browse/trunk/tinypy/... - 136 lines of C code in tinypy. You'll find more examples if you look at other small implementations.

But you also want fast, at which point you have to accept that fast gc == complicated and tightly coupled to the implementation details (object layout, type/debug info).

There is no pluggable GC. Conservative GCs (like Boehm GC) come the closest, but they have significant drawbacks (they blindly scan all of memory and can't tell a difference between a pointer and a random number that looks like a pointer, which means scanning&marking phase take longer and they keep objects that could have been freed, which is especially a problem on 32bits, where it's more likely that a random number points inside GC-managed heap).

(comment deleted)
Pro-tip for google docs: you can use /preview instead of /pub to get a much more readable version of the document (pagination, &c.).