Live data from Hacker News

Generics can make your Go code slower

planetscale.com

31–40 of 418 posts

Re: Generics can make your Go code slower

#31

Well sure. Not writing hand tuned assembly can make your code slower, too. Go's value as a language is how it fills the niche between Rust and Python, giving you low level things like manual memory control, while still making tradeoffs for performance and developer experience.

I might have worded it differently, but yeah, of cause generics can make your code slower, what did people expect.

I would have expected generics to make the compiler take longer, not the compiled program.

Re: Generics can make your Go code slower

#32
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 the monomorphization approach, it would be impossible to back out of it because it would cause performance regressions. Starting with the shape stenciling approach means that introducing monomorphization later can give you a performance improvement.

I'm not trying to predict whether we'll get monomorphization at some future point in Go, but I'm just saying that at least the door is open.

Re: Generics can make your Go code slower

#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?

Re: Generics can make your Go code slower

#34
Great article, just skimmed it, but will definitely dive deeper into it. I thought Go is doing full monomorphization.

As another datapoint I can add that I tried to replace the interface{}-based btree that I use as the main workhorse for grouping in OctoSQL[0] with a generic one, and got around 5% of a speedup out of it in terms of records per second.

That said, compiling with Go 1.18 vs Go 1.17 got me a 10-15% speedup by itself.

[0]:https://github.com/cube2222/octosql

Re: Generics can make your Go code slower

#35

Earlier quoted context omitted.

I might have worded it differently, but yeah, of cause generics can make your code slower, what did people expect.

It depends what they are replacing. Typically, generics used to replace runtime polymorphism (using [T any] []T instead of []any) would be a speed boost in C#, C++, or Rust; and would have no impact on speed in Java.

And it is also a speed boost in Go, assuming you don't call any methods. (Which, if you were really using [T any], you either weren't or you were dissembling about your acceptable types.)

Re: Generics can make your Go code slower

#36

This is a really long and informative article, but I would propose a change to the title here, since "Generics can make your Go code slower" seems like the expected outcome, where the conclusion of the article leans more towards "Generics don't always make your code slower", as well as enumerating some good ways to use generics, as well as some anti-patterns.

Interestingly the original title and your proposed title imply, to me, the opposite of what I think they imply to you. This suggestion is really unclear.

Re: Generics can make your Go code slower

#37
post #18

what I expect to happen now that golang has generics and reports like these will show up is golang will explore monomorphizing generics and get hard numbers. they may also choose to use some of the compilation speeds they've gained from linker optimizations and spend that on generics. I can't imagine monomorphizing being that big of a deal during compilation if the generation is defered and results are cached.

I am unfamiliar with Go. This article discusses that they have decided to go for runtime lookup. Is there any reason why that implementation might make monomorphizing more difficult?

nope. it was an intentional trade off with respect to compilation speed. once generics have baked for a bit with real world usage said decision will almost certainly be revisited.

edit: for example one could envision the compiler generates the top n specializations per generic function based on usage and then uses the current stuff non-specialized version for the rest.

Re: Generics can make your Go code slower

#38

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…

Yes, they seem to have shipped a MVP first, which is a sensible approach. Controlling the extent of monomorphization requires changes in how the code is written, so if they had offered that exclusively it would've been a pitfall to existing users. By boxing everything, they keep their MVP closer to the previously idiomatic interface{} pattern.

Re: Generics can make your Go code slower

#39

Great article, just skimmed it, but will definitely dive deeper into it. I thought Go is doing full monomorphization. As another datapoint I can add that I tried to replace the interface{}-based btree that I use as the main workhorse for grouping in OctoSQL[0] with a generic one, and got around 5% of a speedup out of it in terms of records per second. That said, compiling with Go 1.18 vs Go 1.17 got me a 10-15% speed…

> That said, compiling with Go 1.18 vs Go 1.17 got me a 10-15% speedup by itself.

Where did you see this speedup? Other than `GOAMD64` there wasn't much in the release notes about compiler or stdlib performance improvements so I didn't rush to get 1.18-compiled binaries deployed, but maybe I should...

(I do expect some nice speedups from using Cut and AvailableBuffer in a few places, but not without some rewrites.)

Post reply on HN