Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Haskell discard a spark when the thunk is garbage collected?

For example:

x :: Maybe a
y :: a
y `par` x `pseq` (fromMaybe y x)

Is the spark of y stopped and discarded if x is computed (much) sooner and is Just ...?

To be more specific, I want to search a list, but each comparison is quite costly. I'd like to parallelize the search, but I'd like the rest of comparisons to be discarded once a match is found.

like image 296
Petr Avatar asked Jan 09 '16 19:01

Petr


People also ask

Does Haskell use garbage collection?

The Haskell runtime system employs a generational garbage collector (GC) with two generations 2. Generations are numbered starting with the youngest generation at zero. Values are always allocated in a special part of the youngest generation called the nursery.

Why does Haskell need garbage collection?

Haskell computations produce a lot of memory garbage - much more than conventional imperative languages. It's because data are immutable so the only way to store every next operation's result is to create new values.


1 Answers

Did you mean fromMaybe instead of maybe?

x `par` y `pseq` (fromMaybe y x)

Also you are creating a spark for evaluating x, not y. So fromMaybe y x will not be evaluated until y is evaluated. Probably you meant the opposite:

y `par` x `pseq` (fromMaybe y x)

If all above is true, then the answer to your question is "no", the spark will not be stopped when already started (though it will be discarded if not yet started.) You can check it with the following test:

import Data.Maybe
import Control.Concurrent
import Control.Parallel
import System.IO.Unsafe
import System.Mem

{-# NOINLINE x #-}
x = unsafePerformIO $ do
  threadDelay 1000
  return (Just 1)

{-# NOINLINE y #-}
y = unsafePerformIO $ do
  print "will eval y"
  threadDelay 3000000
  print "did eval y"
  return (2 :: Int)

main :: IO ()
main = do
  print $ y `par` x `pseq` fromMaybe y x
  print "done"
  performGC
  threadDelay 4000000

The output:

"will eval y"
1
"done"
"did eval y"

Also you can check runtime statistics, +RTS -s. It contains a number of GC'd sparks.

like image 75
Yuras Avatar answered Sep 20 '22 20:09

Yuras