Live data from Hacker News

Faster Sorting with Go Generics

eli.thegreenplace.net

21–30 of 62 posts

Re: Faster Sorting with Go Generics

#21

Are there any good write ups on Go Generics vs other languages for those of us who are familiar with Go but do not write it on a day to day basis? I pick up Go every few months to try new things cause its infinitely easy to setup a web server in Go since it is built-in.

https://planetscale.com/blog/generics-can-make-your-go-code-... made the rounds a few days ago.

Re: Faster Sorting with Go Generics

#22
post #5

> The first thing to note is that there is no dynamic dispatch to the Less method. Each loop iteration invokes cmpstring directly. Except about 95% of the arrays I sort aren't comparable with just <. It's less clear how the unmentioned sort.Slice() will improve.

You'll still have a dynamic Less() equivalent - unless the sorting function gets inlined, which sounds unlikely. But sort.Slice() relies on reflection to do the swapping, which performs even worse than a call to a virtual Swap(). That would now be an ordinary index swap within the sort function. So you'll probably still see major speedups with bubbleSortFunc or some equivalent.

> You'll still have a dynamic Less() equivalent - unless the sorting function gets inlined, which sounds unlikely.

Sorting or ordering?

Using a custom comparator is covered later on, and shows that the ordering function (the custom comparator) is not inlined because of how Go 1.18 groups GC shapes.

However an article from a few days ago (https://planetscale.com/blog/generics-can-make-your-go-code-...) showed that it can be made to work, in some cases, by parametrising the function on the callback. This leads to the sorting function being monomorphised on the callback, and thus the callback (likely) getting inlined.

Re: Faster Sorting with Go Generics

#23
post #14

Earlier quoted context omitted.

Yeah Go is all about "simple, fast enough , compiles fast" So I'd say knobs to control this, which, if you get them wrong, lead to slow compiles, would defnly be contra the spirit of Go. And in cases where absolute max performance really matters, nothing is stopping you from monomorphizin by hand. (But if absolute max perf really matters, you probably picked the wrong language.)

There is no language that writes code as beautiful code as go, at a lower level. C comes close, but C++/Rust are plain ugly, while C is older than some HN users and requires a lot of third-party dependencies for basic operations (e.g http requests).

if err != nil { return nil, err }

code poetry right there. it's so good that you have to repeat this over and over again!

Re: Faster Sorting with Go Generics

#24
I think what people often overlook when discussing generics in Go and code performance that uses generics, is that... the most important thing here is that the code that uses generic sort implementation is: 1. much shorter and more straightforward 2. actually type safe. Even if performance of such code is the same or a bit lower, it does not matter, because the main benefit is that you finally don't have to rely on interfaces (especially an empty one in case of sort.Slice) and have fewer possibilities of runtime panics thanks to that.

Re: Faster Sorting with Go Generics

#25
post #5

Earlier quoted context omitted.

You'll still have a dynamic Less() equivalent - unless the sorting function gets inlined, which sounds unlikely. But sort.Slice() relies on reflection to do the swapping, which performs even worse than a call to a virtual Swap(). That would now be an ordinary index swap within the sort function. So you'll probably still see major speedups with bubbleSortFunc or some equivalent.

> You'll still have a dynamic Less() equivalent - unless the sorting function gets inlined, which sounds unlikely. Sorting or ordering? Using a custom comparator is covered later on, and shows that the ordering function (the custom comparator) is not inlined because of how Go 1.18 groups GC shapes. However an article from a few days ago ( https://planetscale.com/blog/generics-can-make-your-go-code-... ) showed that i…

[deleted]

Re: Faster Sorting with Go Generics

#26

I think what people often overlook when discussing generics in Go and code performance that uses generics, is that... the most important thing here is that the code that uses generic sort implementation is: 1. much shorter and more straightforward 2. actually type safe. Even if performance of such code is the same or a bit lower, it does not matter, because the main benefit is that you finally don't have to rely on i…

> Even if performance of such code is the same or a bit lower, it does not matter

I’m being somewhat pedantic, but that clearly depends on the application.

Re: Faster Sorting with Go Generics

#29

> The first thing to note is that there is no dynamic dispatch to the Less method. Each loop iteration invokes cmpstring directly. Except about 95% of the arrays I sort aren't comparable with just <. It's less clear how the unmentioned sort.Slice() will improve.

The change mentioned at the top of the post (https://go-review.googlesource.com/c/exp/+/378134) also has a benchmark to compare sorting structs using sort.Slice vs a new generic approach that uses a comparison function:

    name           old time/op  new time/op  delta
    SortStructs-8  18.6ms ± 2%  15.9ms ± 3%  -14.43%  (p=0.000 n=10+10)
14.4% is the speedup of the generic version.

The article explains why this happens (towards the end).

Re: Faster Sorting with Go Generics

#30
post #26

I think what people often overlook when discussing generics in Go and code performance that uses generics, is that... the most important thing here is that the code that uses generic sort implementation is: 1. much shorter and more straightforward 2. actually type safe. Even if performance of such code is the same or a bit lower, it does not matter, because the main benefit is that you finally don't have to rely on i…

> Even if performance of such code is the same or a bit lower, it does not matter I’m being somewhat pedantic, but that clearly depends on the application.

You have the freedom to not use generics when the application has stricter performance requirements.
Post reply on HN