Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell : Using unboxed tuples lead to weird types during heap profiling

Initially, I had a piece of code like the following :

data Something = Something !Word32 !Word32

retrieveSomething :: Socket -> IO (Something)
retrieveSomething sock = do
    ...

function sock = do
    (Something x y) <- retrieveSomething sock
    let (a,b,c) = case x of
      0 -> (foo,bar,baz)
      1 -> (foo2,bar2,baz2)
      ...

    doIOwithParams a b c

Which I profiled with the -hy -hC"..." RTS option.

Looking at heap profiles, I had seen that using the 3-tuples consumed way too much memory, so I used unboxed tuples extension (i.e. (# a,b,c #)) which seemed better suited for returning multiple values.

I'm more or less convinced that the heap usage has reduced since I had tested it by making explicit calls to stuff before trying out unboxed tuples, but by doing so, I am now unable to observe different types of values allocated in the cost center.

To clarify the issue a bit more, I could see how much space values of type Something (and anything else) took in the heap after profiling the application without unboxed tuples. Now, there is only a single type to be seen on the heap graph, which I presume to be related to mutable hashtable calls I'm making in the function call.

Is there a way to fix this?

Edit : While it makes perfect sense that unboxed tuples don't appear on the profile, I'm still confused as to why using them hides everything else in the function call/cost center.

I have tried profiling using explicit calls rather than using unboxed tuples, like so :

    case x of
      0 -> doIOwithParams foo bar baz
      1 -> doIOwithParams foo2 bar2 baz2

In addition to being able to see the 3-tuples' overhead is no more, Something and all other types used in the function are also visible, which is contrary to the case I have with unboxed tuples where I can only see the Node type (which may or may not be related to the hashtable I'm using) that takes next to no space compared to other types.

like image 257
felace Avatar asked Dec 30 '12 00:12

felace


1 Answers

I had seen that using the 3-tuples consumed way too much memory, so I used unboxed tuples extension (i.e. (# a,b,c #)) which seemed better suited for returning multiple values.

Just use a regular data type with strict fields. Then GHC can map it to the heap or unboxed tuples on the stack as it sees fit.

data Something = Something {-# UNPACK #-}!Word32 {-# UNPACK #-}!Word32

This has all the benefits of unboxed tuples, and none of the downsides.

like image 139
Don Stewart Avatar answered Oct 07 '22 05:10

Don Stewart