Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make singleton datatypes more efficient in Go #1394

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

tchajed
Copy link
Contributor

@tchajed tchajed commented Aug 27, 2021

Fixes #1214. I'm not very serious about this implementation, I just wanted to show what I managed to do with a little hacking.

Currently, a simple "record" inductive like datatype Astruct = A(x: uint64, y: bool) gets compiled to a Go struct with an interface that only ever has one implementing struct. This creates an unnecessary indirection. This PR replaces that interface with the single constructor's concrete struct type.

The change here is designed to minimize changes to the compiler and share with the case where the datatype has more than one constructor as much as possible. More aggressively for such records we could get rid of the interface type entirely, or also simplify the String() and Equals() implementations. I've benchmarked this change and it does seem to fix the performance problems I had with the normal Dafny output. It's not huge but I do observe a difference, maybe 5% faster for a regular benchmark that shouldn't be bottlenecked on creating structs; an artificial benchmark that creates a lot of structs goes from 83ns to do a functional update to a struct down to 3ns with this PR.

@keyboardDrummer
Copy link
Member

keyboardDrummer commented Aug 27, 2021

I do observe a difference, maybe 5% faster for a regular benchmark that shouldn't be bottlenecked on creating structs; an artificial benchmark that creates a lot of structs goes from 83ns to do a functional update to a struct down to 3ns with this PR.

Having performance tests in Dafny for the generated code would be super useful. I imagine the performance threshold would be configured per output language. Given your interest in GoLang's performance, is adding such a performance test something you're interested in? It could start out small.

RustanLeino
RustanLeino previously approved these changes Sep 16, 2021
Copy link
Collaborator

@RustanLeino RustanLeino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this change.

A similar change would be nice for the other compiler targets as well, but that doesn't need to hold up this PR. For the record (no pun intended), note that the analogous optimization for C# can be done only if all type parameters of the datatype are non-variant, because type variance in C# can only be indicated via an interface. (Oh, but that reminds me--that's not implemented for C# and Java at the moment, anyway.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Singleton datatypes are inefficiently wrapped in interfaces in Go
3 participants