Hacker News new | ask | show | jobs
by 0x62c1b43e 1227 days ago
> The container/heap is more useful, but it could benefit more from adding an optimization for inlining interface method calls when Go compiler knows the underlying implementation behind the interface.

This is exactly what generics do. With e.g. a heap.Heap[uint32] the compiler knows the implementation and there’s no interface method call overhead.

In order for the compiler to do this optimization, it has to know that you don’t e.g. pass a *heap.Heap[uint32] to a function expecting *heap.Heap[uint64], so the type system is what allows it to optimize.

And on top of that, now the user also gets assurance at compile time that heap.Heap[uint32].Pop returns a uint32, preventing bugs from type confusion and also so you don’t have to add type assertions everywhere you use the heap.

So now heap, sort, etc. can benefit from this improved performance; users don’t have to write wrapper types and interface implementations just so their type can be sorted; and bugs are prevented at compile time.

For [1] I posted a reply. It’s true that there are overheads with some slice-returning routines but I explained how in the reply how I viewed the tradeoffs.

1 comments

In theory the compiler can inline interface method calls without the need to introduce generics. For example, it can detect that the customStruct is passed to the sort.Sort() in the code below, and then instantiate the sort.Sort() code for the given inlined Less(), Swap() and Len() interface calls:

    type customStruct struct { ... }
    func (cs *customStruct) Less(i, j int) bool { ... }
    func (cs *customStruct) Swap(i, j int) { ... }
    func (cs *customStruct) Len() int { ... }

    func sortMyCustomStruct(cs *customStruct) {
      sort.Sort(cs)
    }

The tricky part here is that the compiler should be careful when instantiating such calls for different interface implementations, in order to avoid generated code bloat. For example, if sort.Sort() is used for a thousand different sort.Interface implementations, then it may be not a great decision to create a thousand of distinct sort.Sort() instances for every sort.Interface implementation. But this should work OK for a dozen of distinct implementations.