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

Reduce code size with unboxed unary tuples #188

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

treeowl
Copy link
Collaborator

@treeowl treeowl commented Feb 8, 2018

Experimentally make most strict and lazy functions share code
using unboxed unary tuples. I fear we may find this too expensive,
but it's an idea. Needs heavy benchmarking.

Addresses #64

@treeowl treeowl force-pushed the severe-code-size-reduction branch 2 times, most recently from 0046161 to a8b40cb Compare February 8, 2018 09:56
Experimentally make most strict and lazy functions share code
using unboxed unary tuples. I fear we may find this too expensive,
but it's an idea. Needs heavy benchmarking.

Addresses haskell-unordered-containers#64
@treeowl
Copy link
Collaborator Author

treeowl commented Feb 12, 2018

This version has a potential efficiency problem for strict operations. If the passed function doesn't inline, we'll actually build a closure for the function with the type we need. That's not great for insertWith, where we don't have a lot of work over which to amortize the extra cost of allocating the closure. But it's really not good for something like unionWith or insertWith, where we'll pay for the extra indirection every time we need to combine elements.

I realized this evening that if we want to take a walk on the dangerous side, we can probably do it with unsafeCoerce. If we take a function of type a -> a -> a and unsafeCoerce it to a function of type a -> a -> (# a #), what happens? When we case match on the result,

case f a b of
  (# c #) -> ...

GHC will "run" f a b. With a real function of type a -> a -> (# a #), that could produce a thunk. f doesn't really have that type, so running it will produce a value. When we actually use the value, GHC will (unnecessarily) force it again, but that doesn't seem like too big a deal.

The big problem, of course, is that the dangerous version is not remotely supported; if it breaks, we get to keep both pieces.

@sjakobi sjakobi linked an issue May 31, 2020 that may be closed by this pull request
@sjakobi
Copy link
Member

sjakobi commented Jun 24, 2020

I'll mark this as a draft, since it's apparently still WIP.

@sjakobi sjakobi marked this pull request as draft June 24, 2020 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reduce code duplication
2 participants