Live data from Hacker News

Generics can make your Go code slower

planetscale.com

181–190 of 418 posts

Re: Generics can make your Go code slower

#181

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 dev…

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

Re: Generics can make your Go code slower

#182
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…

My argument against GC (and which applies similary to JIT-basd runtimes) is that the problems caused by GC pauses have non-local causes. If a piece of code ran slowly because of a GC pause, the cause of the pause is in some sense _the entire rest of the system_. You can't fix the problem with a localized change.

Programs in un-managed languages can be slow too, and excessive use of malloc() is a frequent culprit. But the difference is that if I have a piece of code that is slow because it is calling malloc() too much, I can often (or at least some of the time) just remove the malloc() calls from that function. I don't have to boil the ocean and significantly reduce the rate at which my entire program allocates memory.

I think another factor that gets ignored is how much you care about tail latency. I think GC is usually fine for servers and other situations where you are targeting a good P99 or P99.9 latency number. And indeed, this is where JVM, Go, node.js, and other GCed runtimes dominate.

But, there are situations, like games, where a bad P99.9 frame time means dropping a frame every 15 seconds (at 60fps). If you've got one frame skip every 10 seconds because of garbage collection pauses and you want to get to one frame skip every minute, that is _not_ an easy problem to fix.

(Yes, I am aware that many commercial game engines have garbage collectors).

Re: Generics can make your Go code slower

#183
post #148

Earlier quoted context omitted.

> 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…

> easily implement for your own types

have you ever actually done that? I have, its not easy. Please dont try to hand wave away negatives of the Rust type system.

Re: Generics can make your Go code slower

#184
post #106

Earlier quoted context omitted.

Ah, that is why all major OSes end up having some form of POSIX support to keep those C applications going.

You need have some OS API, what is wrong with POSIX? And what does POSIX have to do with package management?

POSIX is UNIX rebranded as C runtime for OSes that aren't UNIX.

Re: Generics can make your Go code slower

#185
post #124
post #100

Earlier quoted context omitted.

Java can just be AOT compiled as Go, the only difference is that until recently it wasn't a free beer option to do so.

>until recently Actually, for a long time (almost 20 years, I think), the gcc subsystem gcj let you do AOT compilation of Java to ELF binaries. [1] I think they had to be dynamically linked, but only to a few shared objects (unless you pulled in a lot via native dependencies, but that's kind of "on you"). I don't recall any restrictions on how to use generated code, anymore than gcc-generated object code. So, I don't…

I seldom mention it, because gcj was abandoned in 2009 when most contributors moved into the newly released OpenJDK, eventually removed from GCC tree, and it never was as foolproof as the commercial versions.

Re: Generics can make your Go code slower

#186

Earlier quoted context omitted.

In C++, generics (templates) are zero-cost abstractions. So no, generics do not de facto make code slower.

That's only 99% of the story. :) Having too many specializations of a C++ template can lead to code bloat, which can degrade cache locality, which can degrade performance.

In my experience, code bloat from templates is overblown.

Inlining happens with or without template classes.

Re: Generics can make your Go code slower

#187
post #130

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

The article articulates why it's reasonable to expect that generics would make Go faster. From TFA:

> Monomorphization is a total win for systems programming languages: it is, essentially, the only form of polymorphism that has zero runtime overhead, and often it has negative performance overhead. It makes generic code faster.

Re: Generics can make your Go code slower

#189

I'm excited about generics that gives you a tradeoff between monomorphization and "everything is a pointer". The "everything is a pointer" approach, like Haskell, is incredibly inefficient wrt execution time and memory usage, the "monomorphize everything" approach can explode your code size surprisingly fast. I wouldn't be surprised if we get some control over monomorphization down the line, but if Go started with th…

Why is a speed part of the Go language contract but footprint of the executable is not? I, for one, would be quite miffed if an update of the Go compiler would mean an application would no longer fit on my mcu. That is worse then the application running slower.

> Why is a speed part of the Go language contract but footprint of the executable is not?

Because footprint of the executable has pretty literally never been, Go has always had deficient DCE and generated huge executables.

Re: Generics can make your Go code slower

#190

Earlier quoted context omitted.

In C++, generics (templates) are zero-cost abstractions. So no, generics do not de facto make code slower.

I think his point was that they definitely won't make it faster (more abstraction means more indirection), so the expectation from most (myself included) would be that using them incurs a performance penalty, maybe not directly via their implementation, but via their use in broader terms.

Using templates in C++ can make code faster, though. Because you can write the same routine with more abstraction and less indirection.

I've used C++ templates effectively as a code generator to layer multiple levels of abstractions into completely customized code throughout the abstraction.

Post reply on HN