Go Interface Optimization

From Adam Colton
Jump to navigation Jump to search

One of the complaints about the lack of generics (and one of the few semi-legitimate) is that using interfaces is much slower. But in many cases this could be optimized away.

Say we have interface Fooer and struct Foo. And Foo is the only struct to ever fulfill Fooer. At compile time, all references to Fooer could be replaced with Foo.

Now lets say Fooer is fulfilled by both Foo and Fooish. This starts to get complicated. It may be the case that Foo and Fooish both follow independent paths and we can just duplicate all the code that references Fooer, which doubles the amount of code, but is still simple. But if they interact, it possible to get a much higher multiple, which we don't want.

So the limiting factor becomes how much complexity we'll bear. I think a good default is 2x - if two types independently and exclusively fulfill an interface, go ahead. I think it would also work to have this be a flag or environment variable. It's related to O. So setting it to 0 would mean never, setting it to any int would limit it to that many independent structs.

 Func F() Fooer

If F can return 2 different concrete types - game over.

 func F(f Fooer)Fooer

If the return type is constant or it always returns the type of "f", we're ok.

 func F(a,b Fooer)

With N types of Fooer, there can be up to N2 versions. But it might also be much less.

If I want to pursue this, I think these would be the steps:

  1. Look at the current compiler optimizations to get an idea for how they work
  2. Try building a stand alone tool to do the analyis. See how many projects you can find that would benefit.

Then get some community feedback and possibly open a ticket.