aljce / unpacked-maybe

BSD 3-Clause "New" or "Revised" License
8 stars 1 forks source link

Describe performance benefits more precisely in the README #5

Open chshersh opened 5 years ago

chshersh commented 5 years ago

First of all, thank's for writing this package! The code quality is very good and the sources really help a lot to build something similar using the UnboxedSums extension.

I just wonder, do you know any ways to measure precise performance benefits on this data type compared to ordinary Maybe?

Thanks in advance for your answer!

chessai commented 5 years ago

For reference: there is also unpacked-either, unpacked-validation, unpacked-maybe-numeric, and some other things that I forget currently.

The whole idea behind this is to remove indirections. For example, consider a haskell value of type Maybe a:

v :: Maybe a

v is a thunk, and will always be. So to evaluate v, we must evaluate the thunk. v could evaluate to 1 of 2 things; Nothing or Just.

Nothing leads to no more indirection.

Just contains a pointer to some thunk on the heap. We must chase that pointer and evaluate this thunk. So, we have a minimum of 3 heap indirections for evaluating a Just value.

Also note that GHC cannot perform nested unwrappings, so the value inside the Just can never be unboxed at compile time.

In unpacked-maybe, we shave off an indirection immediately because our Maybe value is not a thunk. Additionally, a Just value does not need to pointer chase to get to the thunk, it's sitting right there in contiguous memory, so that's another indirection saved.

because GHC is very good at performing worker-wrapper on single-field constructors, the Maybe itself usually won't be a thunk at all, and will just unwrap to (# (# #) | a #). Case of known constructor should work here as well.

On Wed, Aug 28, 2019, 3:01 PM Dmitrii Kovanikov notifications@github.com wrote:

First of all, thank's for writing this package! The code quality is very good and the sources really help a lot to build something similar using the UnboxedSums extension.

I just wonder, do you know any ways to measure precise performance benefits on this data type compared to ordinary Maybe?

Thanks in advance for your answer!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/mckeankylej/unpacked-maybe/issues/5?email_source=notifications&email_token=AEOIX25LE3BIA5L3H6H543TQG3DRHA5CNFSM4IRQCTK2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HIAHZRQ, or mute the thread https://github.com/notifications/unsubscribe-auth/AEOIX26XZBTUX4WG25N6NPTQG3DRHANCNFSM4IRQCTKQ .

chessai commented 5 years ago

To measure precise performance, I think benchmarks should be written for all the unpacked-* libraries. Particularly weigh microbenchmarks

On Wed, Aug 28, 2019, 4:18 PM chessai . chessai1996@gmail.com wrote:

For reference: there is also unpacked-either, unpacked-validation, unpacked-maybe-numeric, and some other things that I forget currently.

The whole idea behind this is to remove indirections. For example, consider a haskell value of type Maybe a:

v :: Maybe a

v is a thunk, and will always be. So to evaluate v, we must evaluate the thunk. v could evaluate to 1 of 2 things; Nothing or Just.

Nothing leads to no more indirection.

Just contains a pointer to some thunk on the heap. We must chase that pointer and evaluate this thunk. So, we have a minimum of 3 heap indirections for evaluating a Just value.

Also note that GHC cannot perform nested unwrappings, so the value inside the Just can never be unboxed at compile time.

In unpacked-maybe, we shave off an indirection immediately because our Maybe value is not a thunk. Additionally, a Just value does not need to pointer chase to get to the thunk, it's sitting right there in contiguous memory, so that's another indirection saved.

because GHC is very good at performing worker-wrapper on single-field constructors, the Maybe itself usually won't be a thunk at all, and will just unwrap to (# (# #) | a #). Case of known constructor should work here as well.

On Wed, Aug 28, 2019, 3:01 PM Dmitrii Kovanikov notifications@github.com wrote:

First of all, thank's for writing this package! The code quality is very good and the sources really help a lot to build something similar using the UnboxedSums extension.

I just wonder, do you know any ways to measure precise performance benefits on this data type compared to ordinary Maybe?

Thanks in advance for your answer!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/mckeankylej/unpacked-maybe/issues/5?email_source=notifications&email_token=AEOIX25LE3BIA5L3H6H543TQG3DRHA5CNFSM4IRQCTK2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HIAHZRQ, or mute the thread https://github.com/notifications/unsubscribe-auth/AEOIX26XZBTUX4WG25N6NPTQG3DRHANCNFSM4IRQCTKQ .

chessai commented 5 years ago

The formatting from email truly is terrible.

chshersh commented 5 years ago

It's also interested to know how the benchmarks should look like :thinking:

I've tried to compare the memory size of ordinary Maybe and unpacked Maybe using ghc-datasize packages. It shows with recursiveSizeNF that Just 3 :: Maybe Int occupies 32 bytes. But Unpacked.just 3 :: Unpacked.Maybe Int with recursiveSize shows 8 bytes. However, I'm not sure how to interpret these results: