Hacker News new | ask | show | jobs
by mining 3136 days ago
I don't know. That seemed like a fairly simple exploration of the problem and an easy library function to solve it. Would it be much simpler in any other language?
2 comments

It's a simple problem with a simple fix, from a very simple benchmark - but it's already reaching the limits of how much tuning Go offers. If even such a basic benchmark needed one GC tuning knob, that seems suggestive that maybe a larger and more complex program really would need all the knobs that Java offers, the ones that Go claims are unnecessary.

Or maybe not - maybe that one knob really can solve all the problems. But I really was surprised that anyone would ever need to actively configure a GC for such a simple use case, so I've learnt something at least.

If you need the machinery Java has, you're already fucked. To a first approximation, no one knows how to tune a JVM. Whole books have been written multiple times on the subject, and everywhere I've been that used large-scale Java applications, tuning failures are still at or near the top of the list of most common production issues.

We don't appear to be much better off than we were with C. I guess the server melting is probably preferable to an exploitable smashed stack, but prevention of both issues appears to be to hire geniuses who don't make mistakes while doing enormously mistake-prone work.

> We don't appear to be much better off than we were with C. I guess the server melting is probably preferable to an exploitable smashed stack, but prevention of both issues appears to be to hire geniuses who don't make mistakes while doing enormously mistake-prone work.

"Everyone gets correctness, you need geniuses to get maximum performance" is a huge improvement over the reverse.

Except I see tons of outages caused by things like VM and application server tuning. Software that isn't working isn't correct or performing well.
Not running at all, while not ideal, is a lot better than silent data corruption.
"more complex program really would need all the knobs that Java offers, the ones that Go claims are unnecessary." - but that is really a move in the wrong direction... it's meta programming with Env variables, allocation sizes, command lines, and JDK versions. Sure, Go will probably eventually have all that, to support more tuning, but at that point, ti feels the war for "simple, predictable, low-overhead GC" has been lost, yet again.
> Sure, Go will probably eventually have all that, to support more tuning, but at that point, ti feels the war for "simple, predictable, low-overhead GC" has been lost, yet again.

Well, it seems we don't have a simple GC that performs well in all cases, and really why would we expect to? So choosing simplicity means leaving performance on the table, at least for now, and while there are languages that do that (Python) it doesn't seem like a good fit for Go.

> "it seems we don't have a simple GC that performs well in all cases" Exactly, and after 20+ years, it may be that it's not possible to have such a GC.
I think most pathological cases can be reduced to similarly simple examples. I'm sure these exist for other GCs as well.
Yes, the take-away here is not that Go is particularly bad, but that GCs are problematic. Notably, GC != automatic memory management.
That's not a reasonable conclusion to draw. You would need to preallocate to maximize performance regardless of GC in this case, and in other cases, the performance and determinism gaps between GC languages and non-GC languages is almost entirely due to tertiary factors. For example, GC languages are more likely to prioritize friendliness over raw performance in other areas--language features, compiler optimizations, standard library design, etc. Non-GC languages really only need to appeal to the high-performance and high-determinism crowds.
> Notably, GC != automatic memory management.

Actually, GC == automatic memory management, just not automatic performant memory management

Simpler would be "just work like I expect".
I think the expectation the Go lot have been working towards is the expectation that individual pauses are very short. Contrast to a Java server GC, aiming towards overall efficiency. (Tell me if I'm wrong, I'm no expert.)
Yes, Go optimizes for low latency and Java for high throughput.
Depends on the Java GC being used.
Granted, but the stock GC is optimized for throughput.
The stock GC on OpenJDK, there are other JVMs to choose from.
As another commented posted elsewhere, GC is all about tradeoffs, and for a govern set of GC tradeoffs there will always be pathological cases. Another GC might work out of the box for this workload, but perform very badly for a workload at which Go's GC excels. As others have already mentioned, the fact that he was so easily able to tune the GC is a testament to Go's simplicity.

There are lots of good criticisms of Go to be had, but it's runtime is pretty remarkable, in my opinion.

What about the use cases where what you expect is not what I expect? GC is, as a sibling comment says, about compromises around memory safety.
Doesn't work with GCs.

As another comment in this thread explained, GCs have CPU and Memory tradeoffs and you can easily make a GC that would work excellent in the OP benchmark but would suffer severely under other workloads.