Live data from Hacker News

Generics can make your Go code slower

planetscale.com

141–150 of 418 posts

Re: Generics can make your Go code slower

#141
post #43

Earlier quoted context omitted.

In practice, it's used as an alternative to python and ruby and nodejs. It can't fully do what Java or C# do.

Well, that is simply not true at all. Go is a perfectly capable replacement for Java and C#. Many huge projects that would likely never be written in Python have been written in Go when they would have otherwise been written in Java or C# in years past: Kubernetes, Prometheus, HashiCorp Vault and Terraform, etcd, CoreDNS, TiDB, Loki, InfluxDB, NATS, Docker, Caddy, Gitea, Drone CI, Faktory, etc. The list goes on and o…

> What, exactly, are you saying that Go can't do that Java can?

Runtime library addition (plugins) and dependency injection are two big ones. (We can argue the merit separately, but they're not possible in Go)

I think if Java had easily distributable static binaries k8s would have stayed Java (it started out as Java).

Re: Generics can make your Go code slower

#142
post #33
post #29

My first use of Go generics has been for a concurrent "ECS" game engine. In this case, the gains are pretty obvious. I think. I get to write one set of generic methods and data structures that operate over arbitrary "Component" structs, and I can allocate all my components of a particular type contiguously on the heap, then iterate over them with arbitrary, type-safe functions. I can't fathom that doing this via a Co…

Sounds interesting, is it available somewhere?

Still want to hit some milestones before releasing anything, so not quite

Re: Generics can make your Go code slower

#143

Earlier quoted context omitted.

I have a slightly contrary opinion. Systems software is a very large umbrella, and much under that umbrella is not encumbered by a garbage collector whatsoever. (To add insult to injury, the term's definition isn't even broadly agreed upon, similar to the definition of a "high-level language".) Yes, there are some systems applications where a GC can be a hindrance in practice, but these days I'm not even sure it's a…

The article is from a database company, so I'll assume that approximates the scope. My scope for the GC discussion would include other parts that could be considered similar software: cluster-control plane (Kubernetes), other databases, and possibly the first level of API services to implement a service like an internal users/profiles or auth endpoints. The tricky thing is GC works most of the time, but if you are wo…

Go doesn’t offer a bunch of GC tuning parameters. Really only one parameter, so your concerns about complex GC tuning here seem targeted at some other language like Java.

This is a drawback in some cases, since one size never truly fits all, but it dramatically simplifies things for most applications, and the Go GC has been tuned for many years to work well in most places where Go is commonly used. The developers of Go continue to fix shortcomings that are identified.

Go’s GC prioritizes very short STWs and predictable latency, instead of total GC throughput, and Go makes GC throughput more manageable by stack allocating as much as it can to reduce GC pressure.

Generally speaking, Go is also known for using very little memory compared to Java.

Re: Generics can make your Go code slower

#144
post #135

Earlier quoted context omitted.

This is an argument from edge case capabilities that completely ignores maintenance costs + development time. Seems very naive to me.

It's not. If you are building a database or other "systems" software these are very relevant capabilities. Also development time of Java may be slightly longer in the early stages but I generally find refactoring of Java projects and shuffling of timelines etc is a ton easier than Go. So I think Java wins out over a longer period of time even if it starts off a bit slower. It's far from naive. I have written a shitto…

You may not personally be naive, but i was talking about your analysis, not you.

>Also development time of Java may be slightly longer in the early stages but I generally find refactoring of Java projects and shuffling of timelines etc is a ton easier than Go. So I think Java wins out over a longer period of time even if it starts off a bit slower.

I think this topic is far too large to be answered in this brief sentence. I also think it deserves a higher allocation of your words than what you spared for java's capabilities :)

But yes, I see now that you are interested purely in performance in your argument and definition of systems software, in which case what you're saying may be true.

Re: Generics can make your Go code slower

#145
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.

Re: Generics can make your Go code slower

#146
post #81
post #46

I'd argue that golang is inherently not a systems language, with its mandatory GC managed memory. I think it's a poor choice for anything performance or memory sensitive, especially a database. I know people would disagree (hence all the DBs written in golang these days, and Java before it), but I think C/C++/Rust/D are all superior for that kind of application. All of which is to say, I don't think it matters. Use t…

You really haven't given any supporting information for your argument other than a vague feeling that GC is somehow bad. In fact you just pointed out many counterexamples to your own argument, so I'm not sure what to take away. I've seen this sentiment a lot, and I never see specifics. "GC is bad for systems language" is an unsupported, tribalist, firmly-held belief that is unsupported by hard data. On the other hand…

GC is bad if the problem domain you are working on requires you to think about the behaviour of the GC all the time. GC behaviour can be subtle, may change from version to version and some behaviours may not even be clearly documented. If one has to think about it all the time, it is likely better just to use a tool where memory management is more explicit. However, I think for many examples of "systems software" (Kubernetes for example), GC is not an issue at all but for others it is an illogical first choice (though it often can be made to work).

Re: Generics can make your Go code slower

#147
post #87

Earlier quoted context omitted.

What, specifically, do you mean when you say Rust is "awful to work with"? With C and C++ I agree, but I've had a drastically better development experience in Rust than Go.

You should probably read the rest of the comment...

Are Result and Option really the only thing? Because nesting scopes based on Err/None is rarely the right choice, just like nesting a scope based on `if err == nil` isn't typically something you want to do in Go, or `if errno == 0` in C

  - You can panic trivially with `.unwrap()`
  - You can propagate the condition up trivially with `?`
    - `?` doesn't work with all types, but it does work with Option, and it does work with the vast majority of error types - making your custom error work with it is very easy (if you're whipping up an application or prototype and want your error handling very simple, `anyhow::Error` works great here)
  - You can convert None to an Err condition trivially with `.ok_or()?`
  - In cases where it makes sense, you can trivially use a default value with `.unwrap_or_default()`
And all of these use require a _lot_ less code than `if err != nil { return nil, err }`

And all of these allow you to use the Ok/Some value directly in a function call, or in a method chain, while still enabling the compiler to force you to handle the Err/None case

The common theme here being "trivial" :) Result/Option are a big piece of that better developer experience.

Re: Generics can make your Go code slower

#148

Earlier quoted context omitted.

I've found Go to be much simpler than Rust, especially syntax wise. However, in Rust you can use the ? operator which propagates errors. In Go you have to check err != nil.

> Rust you can use the ? operator That doesnt work with all types: https://stackoverflow.com/a/65085003

It works for any type that implements the `std::error::Error` trait; which is something you can easily implement for your own types. If you want your errors to be integers for some reason, you can wrap that type in a zero-sized "newtype" wrapper, and implement `Error` for that.

The Stack Overflow answer you linked seems to be claiming that it's simply easier to return strings, but I wouldn't say this is a restriction imposed by the language.

Re: Generics can make your Go code slower

#149
post #130

Seems obvious; like, did someone expect all the extra abstraction would make Go faster?

What extra abstraction?

I'd expect without monomorphization the code should perform the same as interface{} code, perhaps minus type cast error handling overhead. That's the model where generics are passing interface{} underneath, & exist only as a type check (à la Java type erasure)

Re: Generics can make your Go code slower

#150
post #46

I'd argue that golang is inherently not a systems language, with its mandatory GC managed memory. I think it's a poor choice for anything performance or memory sensitive, especially a database. I know people would disagree (hence all the DBs written in golang these days, and Java before it), but I think C/C++/Rust/D are all superior for that kind of application. All of which is to say, I don't think it matters. Use t…

The GC in Go is not mandatory.

In the language? In the implementation?
Post reply on HN