Skip to content

Instantly share code, notes, and snippets.

@cnd
Last active December 10, 2015 23:28
Show Gist options
  • Save cnd/4509874 to your computer and use it in GitHub Desktop.
Save cnd/4509874 to your computer and use it in GitHub Desktop.
Gentoo Haskell F#
>>time ./hs 15 ~/tests/ :)
stretch tree of depth 16 check: -1
65536 trees of depth 4 check: -65536
16384 trees of depth 6 check: -16384
4096 trees of depth 8 check: -4096
1024 trees of depth 10 check: -1024
256 trees of depth 12 check: -256
64 trees of depth 14 check: -64
long lived tree of depth 15 check: -1
./hs 15 1.08s user 0.72s system 99% cpu 1.803 total
>>time ./fs.exe 15 ~/tests/ :)
stretch tree of depth 16 check: -1
65536 trees of depth 4 check: -65536
16384 trees of depth 6 check: -16384
4096 trees of depth 8 check: -4096
1024 trees of depth 10 check: -1024
256 trees of depth 12 check: -256
64 trees of depth 14 check: -64
long lived tree of depth 15 check: -1
mono ./fs.exe 15 0.69s user 0.33s system 151% cpu 0.673 total
mono 3.0.3 ; F# git ; GHC 7.6.1 with -threaded
@cnd
Copy link
Author

cnd commented Jan 11, 2013

import System.Environment
import Control.Monad
import System.Mem
import Data.Bits
import Text.Printf
import GHC.Conc

--
-- an artificially strict tree.
--
-- normally you would ensure the branches are lazy, but this benchmark
-- requires strict allocation.
--
data Tree = Nil | Node !Int !Tree !Tree

minN = 4

io s n t = printf "%s of depth %d\t check: %d\n" s n t

main = do
    n <- getArgs >>= readIO . head
    let maxN     = max (minN + 2) n
        stretchN = maxN + 1
    -- stretch memory tree
    let c = {-# SCC "stretch" #-} check (make 0 stretchN)
    io "stretch tree" stretchN c

    -- allocate a long lived tree
    let !long    = make 0 maxN

    -- allocate, walk, and deallocate many bottom-up binary trees
    let vs = depth minN maxN
    mapM_ (\((m,d,i)) -> io (show m ++ "\t trees") d i) vs

    -- confirm the the long-lived binary tree still exists
    io "long lived tree" maxN (check long)

-- generate many trees
depth :: Int -> Int -> [(Int,Int,Int)]
depth d m
    | d <= m    = let 
        s = sumT d n 0
        rest = depth (d+2) m
        in s `par` ((2*n,d,s) : rest)
    | otherwise = []
  where n = bit (m - d + minN)

-- allocate and check lots of trees
sumT :: Int -> Int -> Int -> Int    
sumT d 0 t = t
sumT  d i t = a `par` b `par` sumT d (i-1) ans
  where a = check (make i    d)
        b = check (make (-i) d)
        ans = a + b + t

check = check' True 0

-- traverse the tree, counting up the nodes
check' :: Bool -> Int -> Tree -> Int
check' !b !z Nil          = z
check' b z (Node i l r)   = check' (not b) (check' b (if b then z+i else z-i) l) r

-- build a tree
make :: Int -> Int -> Tree
make i 0 = Node i Nil Nil
make i d = Node i (make (i2-1) d2) (make i2 d2)
  where i2 = 2*i; d2 = d-1

@cnd
Copy link
Author

cnd commented Jan 11, 2013

open System
open Unchecked

type Next = { Left: Tree; Right: Tree }
and [<Struct>] Tree(next:Next,item:int) =
    member t.Check() =
        match box next with 
        | null -> item
        | _ -> item + next.Left.Check() - next.Right.Check()

let rec make item depth =
    if depth > 0 then Tree({Left = make (2*item-1) (depth-1); Right=make (2*item) (depth-1)}, item)
    else Tree(defaultof<_>,item)

let inline check (tree:Tree) = tree.Check()

let rec loopDepths maxDepth minDepth d =
    if d <= maxDepth then
        let niter = 1 <<< (maxDepth - d + minDepth)
        let mutable c = 0
        for i = 1 to niter do
            c <- c + check (make i d) + check (make (-i) d)
        Console.WriteLine("{0}\t trees of depth {1}\t check: {2}",2 * niter,d,c)
        loopDepths maxDepth minDepth (d + 2)

[<EntryPoint>]
let main args =
    let minDepth = 4
    let maxDepth =
        let n = if args.Length > 0 then int args.[0] else 10
        max (minDepth + 2) n
    let stretchDepth = maxDepth + 1

    let c = check (make 0 stretchDepth)
    Console.WriteLine("stretch tree of depth {0}\t check: {1}",stretchDepth,c)
    let longLivedTree = make 0 maxDepth
    loopDepths maxDepth minDepth minDepth
    Console.WriteLine("long lived tree of depth {0}\t check: {1}",maxDepth,(check longLivedTree))
    exit 0

@cnd
Copy link
Author

cnd commented Jan 11, 2013

>>time ./fs.exe 20     
stretch tree of depth 21         check: -1
2097152  trees of depth 4        check: -2097152
524288   trees of depth 6        check: -524288
131072   trees of depth 8        check: -131072
32768    trees of depth 10       check: -32768
8192     trees of depth 12       check: -8192
2048     trees of depth 14       check: -2048
512      trees of depth 16       check: -512
128      trees of depth 18       check: -128
32       trees of depth 20       check: -32
long lived tree of depth 20      check: -1
mono ./fs.exe 20  35.63s user 2.08s system 145% cpu 25.917 total
>>time ./hs 20   
stretch tree of depth 21         check: -1
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it.
./hs 20  4.10s user 1.53s system 99% cpu 5.638 total

:(

@cnd
Copy link
Author

cnd commented Jan 11, 2013

>>time python py.py 15                                                                                                                                                                                 ~/tests/ :)
stretch tree of depth 16         check: -1
65536    trees of depth 4        check: -65536
16384    trees of depth 6        check: -16384
4096     trees of depth 8        check: -4096
1024     trees of depth 10       check: -1024
256      trees of depth 12       check: -256
64       trees of depth 14       check: -64
long lived tree of depth 15      check: -1
python py.py 15  10.99s user 0.16s system 357% cpu 3.121 total
from __future__ import print_function

import sys
import multiprocessing as mp


def make_tree(i, d):

    if d > 0:
        i2 = i + i
        d -= 1
        return (i, make_tree(i2 - 1, d), make_tree(i2, d))
    return (i, None, None)


def check_tree(node):

    (i, l, r) = node
    if l is None:
        return i
    else:
        return i + check_tree(l) - check_tree(r)


def make_check(itde, make=make_tree, check=check_tree):

    i, d = itde
    return check(make(i, d))


def get_argchunks(i, d, chunksize=5000):

    assert chunksize % 2 == 0
    chunk = []
    for k in range(1, i + 1):
        chunk.extend([(k, d), (-k, d)])
        if len(chunk) == chunksize:
            yield chunk
            chunk = []
    if len(chunk) > 0:
        yield chunk


def main(n, min_depth=4):

    max_depth = max(min_depth + 2, n)
    stretch_depth = max_depth + 1
    if mp.cpu_count() > 1:
        pool = mp.Pool()
        chunkmap = pool.map
    else:
        chunkmap = map

    print('stretch tree of depth {0}\t check: {1}'.format( 
          stretch_depth, make_check((0, stretch_depth))))

    long_lived_tree = make_tree(0, max_depth)

    mmd = max_depth + min_depth
    for d in range(min_depth, stretch_depth, 2):
        i = 2 ** (mmd - d)
        cs = 0
        for argchunk in get_argchunks(i,d):
            cs += sum(chunkmap(make_check, argchunk))
        print('{0}\t trees of depth {1}\t check: {2}'.format(i * 2, d, cs))

    print('long lived tree of depth {0}\t check: {1}'.format( 
          max_depth, check_tree(long_lived_tree)))


if __name__ == '__main__':
    main(int(sys.argv[1]))

@cnd
Copy link
Author

cnd commented Jan 11, 2013

>>time ./hs 15 +RTS -N                                                                                                                                                                                 ~/tests/ :)
stretch tree of depth 16         check: -1
65536    trees of depth 4        check: -65536
16384    trees of depth 6        check: -16384
4096     trees of depth 8        check: -4096
1024     trees of depth 10       check: -1024
256      trees of depth 12       check: -256
64       trees of depth 14       check: -64
long lived tree of depth 15      check: -1
./hs 15 +RTS -N  2.03s user 1.38s system 282% cpu 1.207 total
>>time mono --llvm fs.exe 15                                                                                                                                                                           ~/tests/ :)
stretch tree of depth 16         check: -1
65536    trees of depth 4        check: -65536
16384    trees of depth 6        check: -16384
4096     trees of depth 8        check: -4096
1024     trees of depth 10       check: -1024
256      trees of depth 12       check: -256
64       trees of depth 14       check: -64
long lived tree of depth 15      check: -1
mono --llvm fs.exe 15  0.66s user 0.34s system 149% cpu 0.668 total

Haskell code change:

--
-- The Computer Language Benchmarks Game
-- http://shootout.alioth.debian.org/
--
-- Contributed by Don Stewart
-- Parallelized by Louis Wasserman

import System.Environment
import Control.Monad
import System.Mem
import Data.Bits
import Text.Printf
import GHC.Conc

--
-- an artificially strict tree.
--
-- normally you would ensure the branches are lazy, but this benchmark
-- requires strict allocation.
--
data Tree = Nil | Node !Int !Tree !Tree

minN = 4

io s n t = printf "%s of depth %d\t check: %d\n" s n t

main = do
    n <- getArgs >>= readIO . head
    let maxN     = max (minN + 2) n
        stretchN = maxN + 1
    -- stretch memory tree
    let c = {-# SCC "stretch" #-} check (make 0 stretchN)
    io "stretch tree" stretchN c

    -- allocate a long lived tree
    let !long    = make 0 maxN

    -- allocate, walk, and deallocate many bottom-up binary trees
    let vs = depth minN maxN
    mapM_ (\((m,d,i)) -> io (show m ++ "\t trees") d i) vs

    -- confirm the the long-lived binary tree still exists
    io "long lived tree" maxN (check long)

-- generate many trees
depth :: Int -> Int -> [(Int,Int,Int)]
depth d m
    | d <= m    = let 
        s = sumT d n 0
        rest = depth (d+2) m
        in s `seq` ((2*n,d,s) : rest)
    | otherwise = []
  where n = bit (m - d + minN)

-- allocate and check lots of trees
sumT :: Int -> Int -> Int -> Int    
sumT d 0 t = t
sumT d i t = a `par` b `seq` sumT d (i-1) ans
--sumT  d i t = a `par` b `par` sumT d (i-1) ans
  where a = check (make i    d)

@cnd
Copy link
Author

cnd commented Jan 11, 2013

>>time ./hs 15 +RTS -N                                                                                                                                                                                 ~/tests/ :)
stretch tree of depth 16         check: -1
65536    trees of depth 4        check: -65536
16384    trees of depth 6        check: -16384
4096     trees of depth 8        check: -4096
1024     trees of depth 10       check: -1024
256      trees of depth 12       check: -256
64       trees of depth 14       check: -64
long lived tree of depth 15      check: -1
./hs 15 +RTS -N  2.13s user 0.99s system 367% cpu 0.849 total
>>time mono --llvm fs.exe 15                                                                                                                                                                           ~/tests/ :)
stretch tree of depth 16         check: -1
65536    trees of depth 4        check: -65536
16384    trees of depth 6        check: -16384
4096     trees of depth 8        check: -4096
1024     trees of depth 10       check: -1024
256      trees of depth 12       check: -256
64       trees of depth 14       check: -64
long lived tree of depth 15      check: -1
mono --llvm fs.exe 15  0.74s user 0.28s system 149% cpu 0.683 total

haskell code change:

--
-- The Computer Language Benchmarks Game
-- http://shootout.alioth.debian.org/
--
-- Contributed by Don Stewart
-- Parallelized by Louis Wasserman

import System.Environment
import Control.Monad
import System.Mem
import Data.Bits
import Text.Printf
import GHC.Conc

--
-- an artificially strict tree.
--
-- normally you would ensure the branches are lazy, but this benchmark
-- requires strict allocation.
--
data Tree = Nil | Node !Int !Tree !Tree

minN = 4

io s n t = printf "%s of depth %d\t check: %d\n" s n t

main = do
    n <- getArgs >>= readIO . head
    let maxN     = max (minN + 2) n
        stretchN = maxN + 1
    -- stretch memory tree
    let c = {-# SCC "stretch" #-} check (make 0 stretchN)
    io "stretch tree" stretchN c

    -- allocate a long lived tree
    let !long    = make 0 maxN

    -- allocate, walk, and deallocate many bottom-up binary trees
    let vs = depth minN maxN
    mapM_ (\((m,d,i)) -> io (show m ++ "\t trees") d i) vs

    -- confirm the the long-lived binary tree still exists
    io "long lived tree" maxN (check long)

-- generate many trees
depth :: Int -> Int -> [(Int,Int,Int)]
depth d m
    | d <= m    = let 
        s = sumT d n 0
        rest = depth (d+2) m
        in s `par` rest `seq` ((2*n,d,s) : rest)
    | otherwise = []
  where n = bit (m - d + minN)

-- allocate and check lots of trees
sumT :: Int -> Int -> Int -> Int    
sumT d 0 t = t
sumT d i t = a `par` b `seq` sumT d (i-1) ans
--sumT  d i t = a `par` b `par` sumT d (i-1) ans
  where a = check (make i    d)
        b = check (make (-i) d)
        ans = a + b + t

check = check' True 0

-- traverse the tree, counting up the nodes
check' :: Bool -> Int -> Tree -> Int
check' !b !z Nil          = z
check' b z (Node i l r)   = check' (not b) (check' b (if b then z+i else z-i) l) r

-- build a tree
make :: Int -> Int -> Tree
make i 0 = Node i Nil Nil
make i d = Node i (make (i2-1) d2) (make i2 d2)
  where i2 = 2*i; d2 = d-1

@cnd
Copy link
Author

cnd commented Jan 11, 2013

>>time ./hs 17 +RTS -N                                                                                                                                                                                 ~/tests/ :(
stretch tree of depth 18         check: -1
262144   trees of depth 4        check: -262144
65536    trees of depth 6        check: -65536
16384    trees of depth 8        check: -16384
4096     trees of depth 10       check: -4096
1024     trees of depth 12       check: -1024
256      trees of depth 14       check: -256
64       trees of depth 16       check: -64
long lived tree of depth 17      check: -1
./hs 17 +RTS -N  10.37s user 4.39s system 385% cpu 3.825 total
>>time mono --llvm fs.exe 17                                                                                                                                                                           ~/tests/ :)
stretch tree of depth 18         check: -1
262144   trees of depth 4        check: -262144
65536    trees of depth 6        check: -65536
16384    trees of depth 8        check: -16384
4096     trees of depth 10       check: -4096
1024     trees of depth 12       check: -1024
256      trees of depth 14       check: -256
64       trees of depth 16       check: -64
long lived tree of depth 17      check: -1
mono --llvm fs.exe 17  3.12s user 0.65s system 145% cpu 2.597 total

@cnd
Copy link
Author

cnd commented Jan 11, 2013

>>time mono --llvm fs.exe 18                                                                                                                                                                           ~/tests/ :)
stretch tree of depth 19         check: -1
524288   trees of depth 4        check: -524288
131072   trees of depth 6        check: -131072
32768    trees of depth 8        check: -32768
8192     trees of depth 10       check: -8192
2048     trees of depth 12       check: -2048
512      trees of depth 14       check: -512
128      trees of depth 16       check: -128
32       trees of depth 18       check: -32
long lived tree of depth 18      check: -1
mono --llvm fs.exe 18  7.21s user 0.93s system 142% cpu 5.714 total
>>time ./hs 18 +RTS -N4                                                                                                                                                                                ~/tests/ :)
stretch tree of depth 19         check: -1
524288   trees of depth 4        check: -524288
131072   trees of depth 6        check: -131072
32768    trees of depth 8        check: -32768
8192     trees of depth 10       check: -8192
2048     trees of depth 12       check: -2048
512      trees of depth 14       check: -512
128      trees of depth 16       check: -128
32       trees of depth 18       check: -32
long lived tree of depth 18      check: -1
./hs 18 +RTS -N4  26.23s user 10.98s system 392% cpu 9.487 total

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment