Hacker News new | ask | show | jobs
by zachruss92 1545 days ago
For me Go has replaced Node as my preferred backend language. The reason is because of the power of static binaries, the confidence that the code I write today can still run ten years from now, and the performance.

The difference in the code I’m working with is being able to handle 250 req/s in node versus 50,000 req/s in Go without me doing any performance optimizations.

From my understanding Go was written with developer ergonomics first and performance is a lower priority. Generics undoubtedly make it a lot easier to write and maintain complex code. That may come at a performance cost but for the work I do even if it cuts the req/s in half I can always throw more servers at the problem.

Now if I was writing a database or something where performance is paramount I can understand where this can be a concern, it just isn’t for me.

I’d be very curious what orgs like CockroachDB and even K8s think about generics at the scale they’re using them.

4 comments

Director of engineering for CockroachDB SQL here.

One of the major pain points we have with Go is the lack of language support for monomorphization. We rely on a hand-built monomorphizing code generator [0] to compile CockroachDB's vectorized SQL engine [1]. Vectorized SQL is about producing efficient, type and operator specific code for each SQL operator. As such, we rely on true monomorphization to produce a performant SQL query engine.

I have a hope that, eventually, Go Generics will be performant enough to support this use case. As the author points out, there is nothing in the spec that prevents this potential future! That future is not yet here, but that's okay.

There are probably some less performance-sensitive use cases within CockroachDB's code base that could benefit from generics, but we haven't spend time looking into it yet.

[0]: https://github.com/cockroachdb/cockroach/blob/master/pkg/sql...

[1]: https://www.cockroachlabs.com/blog/how-we-built-a-vectorized...

Underrated post. Fast generics in go in under 30 lines? Thank you.

Feels like this approach could be leveraged to get default parameters / optional parameters in Golang too! The Go AST / token lib seems ridiculously flexible.

Huge CockroachDB fan btw. Thanks for the revolution in databases!

PS: Showcase of the awesome Go AST / token lib if you're a Python fan: http://igo.herokuapp.com/

Go was created with simplicity of feature set in mind, which does not translate into developer ergonomics automatically. It rather offers a least common denominator of lang features, so that most devs can handle it, who previously only handled other languages like Java and similar. This way Google aimed at attracting those devs. They'd not have to learn much to make the switch.

True developer ergonomics, as far as a programming language itself goes, stems from language features, which make goals easy to accomplish in little amount of code, in a readable way, using well crafted concepts of the language. Having to go to lengths, because your lang does not support programming language features (like generics in Go for a long time) is not developer ergonomics.

There is the aspect tooling for a language of course, but that has not necessarily to do with programmming language design. Same goes for standard library.

Rob Pike quantifies your sentiment as "Orthogonal Features"[0][1], which isn't necessarily equivalent to "simplicity of feature set". But I do understand what you meant.

I think in this context tho, developer ergonomics can mean different things to different people.

It's easy to see how "Orthogonal Features" can be interpreted as developer ergonomics, as its explicitly limiting potential (not all) anti-patterns and produces fairly idiomatic code across the ecosystem. I'm able to go to almost any Github repo that contains Go code, and easily determine whats going on, whats the flow, etc. Certainly ergonomic in that context.

[0]: https://go.dev/talks/2010/ExpressivenessOfGo-2010.pdf

[1]: https://www.informit.com/articles/article.aspx?p=1623555

250 vs. 50000 req/s seems like a too big of a difference to me. Sure Go is faster than Node but Node is no slough either, you might want to dig in some deeper why you only got 250 req/s with Node.
That could mostly be due to multithreading. That comes free with go but requires a different model in node.
50000/250=200, that is a lot of cores!
That calculation assumes that Go and Node have the same performance and the only gain is by parallelism. But I agree.. the performance difference seems strange. On a 1 core basis I'd expect something like a factor 2-5 gain.
Identical algorithms (e.g. quicksort) run ~40x faster in Go than Ruby in a single thread due to more efficient CPU usage, even when you avoid the kinds of steps that would allocate objects in Ruby. Multiply by 64 cores and it’s easy to observe a 1000x improvement with very little difference in the code.
Doesn't sound unrealistic if you have a mix load of IO and raw processing.
> The difference in the code I’m working with is being able to handle 250 req/s in node versus 50,000 req/s in Go without me doing any performance optimizations.

Your node code should be in the 2k reqs/s range trivially, with many frameworks comfortable offering 5k+.

It is never going to be as fast as go, but it will handle most cases.

How can you make these claims without information about what his application handles requests? Not everything is a trivial database read/write op.
esbuild is 100x faster than js build tools, so in general 100x speed up sounds about right.
Sucrase, written in Typescript, claims to be 2x faster than esbuild.

I'll leave you to your own benchmarks.

Sucrase does this by removing some things you might expect to be table stakes, like detecting invalid parse trees and complete JS syntax. Pragmatically, esbuild can also start faster and parallelize, which means shorter wall-clock builds.
Sure, but esbuild also drops features found in the compared tools to gain a performance edge. The language may bring some marginal difference, but it's clear that the algorithm is the most significant piece.