
Overhead of Go’s Generic Sort - nieksand
https://github.com/nieksand/sortgenerics
======
JulienSchmidt
The problem is that it operates on an abstract interface but it is NOT
generic. With any Generics implementation that generates code for the specific
type under the hood (e.g. at compile-time like C++ Templates or Rust Traits,
or just-in-time), there would be no overhead.

~~~
mjburgess
Yeah, this is what you get when your language does not support generics.

~~~
amelius
True. But a compiler can also perform inference, and optimize this without
type information.

Of course, it becomes less reliable, because you'd have to trust that the
compiler does this (and consistently over changes to the code).

------
willvarfar
C's qsort() has a similar overhead vs C++ STL's std::sort() for much the same
reason - the C version calls a comparator function but the C++ compiler can
inline the comparator.

~~~
candiodari
And the only way to fix it without generics is with a VM.

~~~
willvarfar
Or whole-program-optimisation or a compiler that has builtins for qsort()
(rather as they all do for malloc/free these days)

~~~
candiodari
I shudder at the thought of compilers with builtins for something as complex
as qsort. But yeah, it would fit with Go's usual way of doing things.

------
JulianMorrison
What I take away from this, is that unless you are spending a lot of run-time
sorting things, or you are sorting a lot of things, you might as well not
bother to micro-optimize.

~~~
stymaar
This article is not about micro-optimisations, it's about mesuring the cost of
dynamic dispatch and virtual fonction call, which cannot be avoided in Go
since there are no generics and the langage relies on interfaces instead.

~~~
gepoch
I agree with you, but in the cases where it really matters you can still avoid
it! There is community activity around code generation to fill in for the
cases where generics would really be the right answer. Basically, you make a
template and render it for your type, check that into source control, and use
as normal.

This removes the dynamic overhead at the cost of having to run a code
generator and maintain a rendered template library in your source. There's
actually language support for hooking into these generators at build time.

~~~
zzzcpan
> There's actually language support for hooking into these generators at build
> time.

Hmm, are you talking about "go generate" or is there a new feature? Because go
generate is not a build time hook, but build time hook would be very useful in
some cases.

------
praptak
I can imagine the overhead for ints is large. But how often do you sort pure
ints? A more realistic test would be some objects sorted on a field value.

~~~
nieksand
That's great feedback. I'll try out this specialization on a simple struct
(int32/string) combo later today. We can still get rid of the indirections
around slice manipulation (Swap and Len) but obviously stay stuck with the
Less.

~~~
pettou
Or try sorting points (struct of two float64s) by the x-coordinate, and
compare the timing with similar JavaScript code running in V8. You might be
surprised...

