Hacker News new | ask | show | jobs
by richieartoul 1338 days ago
I do a lot of “high throughput” stuff at work in both Go and Java, and the Go stuff is usually faster by default.

Java tends to win for really naive programs where the author didn’t bother caring about performance or allocations at all, but if any care was put into it at all Go usually wins in my experience.

The trope that Go’s GC is primitive in comparison to Javas is not really accurate. You can’t consider a language’s GC in isolation.

Java’s GC and JIT are extremely complex because the language semantics are terrible for performance by default. The “everything is an object” model made sense when the language was designed and main memory access times were roughly equal to a CPU cycles, but that’s no longer true by a factor 100 to 200 now.

Go’s GC makes different trade offs (low latency, extremely high concurrency, tight integration with the runtime and scheduler) because the language semantics are much more sympathetic to modern hardware (“true” structs, automatic escape analysis, etc), so it can.

1 comments

Sure, Go can get away with more primitive GC exactly because it has “value types”, so less garbage is created. But they are still much worse, lower latency only means that they pause threads to get more breathing space if they have been allocating too heavily, they are absolutely not even close to the same league Java’s low latency ZGC does.
> they are absolutely not even close to the same league Java’s low latency ZGC does

This is the kind of thing always offered without any serious numbers extracted from real life or even realistic test programs.

So even if technically true in very narrow sense it is more of high performance car marketing with fancy algorithm and data structure names. By the time GC are used in end user programs with tons of libraries, frameworks, design patterns and inefficient to implement business rules those GCs show little difference that fancy ads promised on TV.

It’s really the usage of the word primitive that I’m arguing with. Java’s GC comes with a lot of additional trade offs that Go’s doesn’t.

For example, the fact that the Java GC is copying and generational means that there is a LOT more overhead introduced by write barriers.

If you benchmark the rate at which the GCs can clean up garbage, Java always wins, but the Java GC impairs you a lot more in other situations that the Go one doesn’t.

It’s trade offs, but the Go one makes much better trade offs for modern hardware IMO.

Write barriers are a single local conditional on the fast path, if I’m not mistaken. Also, since a JIT compiler is in action, it may have a much wider range than every object interaction. It’s basically free on modern computers with branch prediction.

ZGC (the low-lat GC) does employ read barriers though which will decrease throughput considerably, but latency and throughput are almost universally opposites of each other.

Do you have benchmarks you can share?
Well, cross-language benchmarking is always hard, but for purely testing the GC this is not too bad: https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

See how ahead Java is of any other managed language (and it doesn’t really make sense to do this benchmark with non-GCd languages)? Though this is done with the G1 GC, not the low-latency one - this default GC is more throughput oriented with a max pause time target goal. Also note how Java does use multiple times more memory, as it “postpones running GC when it knows it still will have enough time to collect all of it without running out of the target goal” - this is also the reason why java is quite ahead on “energy efficiency” reports as well. And also, GCs work better with more heap space.

> this is also the reason why java is quite ahead on “energy efficiency” reports as well.

Very soon businesses would be asking for "dollar efficiency" also. I think going by effort on Java and their frameworks vendors to pack more instances of Java process/pods on a VM, it is already been asked by tech savvy customers.

So that old fact that on sever side programing customers only care for raw throughput and not on machine size because RAM/CPU/disk is cheap is not working well in cloud based deployments where now each of these matter.

To be honest, I really don’t get this microservice/cloud hype, stackoverflow (which let’s be honest will be bigger than that 34th startup) runs on a single (very beefy though) dedicated server machine.

I pay like 5 dollars a month for a VM with very low params, but even that will happily run anything. Especially that the DB likely can’t be shared the bus factor will remain 1.

> To be honest, I really don’t get this microservice/cloud hype, ..

I agree on that. And the bureaucracy evolved around "Microservice Architecture" of Kube pods, service mesh and so many other pieces required for it feel like something we are trying to do it well, what should not be done in first place.