Last active
May 22, 2018 23:01
-
-
Save snoyberg/d6c30825718eaf2aaea4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import qualified Data.ByteString.Lazy as L | |
import Data.Word (Word8) | |
data Stats = Stats | |
{ total :: Int | |
, count :: Int | |
} | |
initStats :: Stats | |
initStats = Stats 0 0 | |
addStat :: Int -> Stats -> Stats | |
addStat x (Stats t c) = Stats (t + x) (c + 1) | |
average :: Stats -> Double | |
average (Stats t c) = fromIntegral t / fromIntegral c | |
fileName :: FilePath | |
fileName = "sample-data.bin" | |
population :: Int | |
population = 9 | |
addStats :: [Stats] -> [Word8] -> [Stats] | |
addStats stats0 bytes0 = | |
loop [] stats0 bytes0 | |
where | |
loop front stats [] = reverse front ++ stats | |
loop front [] bytes = loop [] (reverse front) bytes | |
loop front (x:stats) (y:bytes) = loop | |
(addStat (fromIntegral y) x:front) | |
stats | |
bytes | |
main :: IO () | |
main = do | |
lbs <- L.readFile "sample-data.bin" | |
let initial = replicate population initStats | |
final = addStats initial (L.unpack lbs) | |
print $ map average final | |
{- | |
[127.436561,127.449141,127.64308,127.551385,127.479474,127.457795,127.577525,127.697076,127.463543] | |
2,948,968,072 bytes allocated in the heap | |
4,447,810,144 bytes copied during GC | |
397,149,080 bytes maximum residency (24 sample(s)) | |
48,124,104 bytes maximum slop | |
1065 MB total memory in use (0 MB lost due to fragmentation) | |
Tot time (elapsed) Avg pause Max pause | |
Gen 0 5574 colls, 0 par 0.340s 2.030s 0.0004s 0.0014s | |
Gen 1 24 colls, 0 par 1.440s 1.706s 0.0711s 0.2660s | |
INIT time 0.000s ( 0.000s elapsed) | |
MUT time 0.252s ( 1.178s elapsed) | |
GC time 1.780s ( 3.737s elapsed) | |
EXIT time 0.000s ( 0.004s elapsed) | |
Total time 2.032s ( 4.919s elapsed) | |
%GC time 87.6% (76.0% elapsed) | |
Alloc rate 11,702,254,253 bytes per MUT second | |
Productivity 12.4% of total user, 5.1% of total elapsed | |
real 0m4.923s | |
user 0m2.032s | |
sys 0m2.884s | |
-} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -exuo pipefail | |
dd if=/dev/urandom of=sample-data.bin bs=9000 count=1000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import qualified Data.ByteString.Lazy as L | |
import Data.Word (Word8) | |
data Stats = Stats | |
{ total :: !Int | |
, count :: !Int | |
} | |
initStats :: Stats | |
initStats = Stats 0 0 | |
addStat :: Int -> Stats -> Stats | |
addStat x (Stats t c) = Stats (t + x) (c + 1) | |
average :: Stats -> Double | |
average (Stats t c) = fromIntegral t / fromIntegral c | |
fileName :: FilePath | |
fileName = "sample-data.bin" | |
population :: Int | |
population = 9 | |
addStats :: [Stats] -> [Word8] -> [Stats] | |
addStats stats0 bytes0 = | |
loop [] stats0 bytes0 | |
where | |
loop front stats [] = reverse front ++ stats | |
loop front [] bytes = loop [] (reverse front) bytes | |
loop front (x:stats) (y:bytes) = y' `seq` loop | |
(y':front) | |
stats | |
bytes | |
where | |
y' = addStat (fromIntegral y) x | |
main :: IO () | |
main = do | |
lbs <- L.readFile "sample-data.bin" | |
let initial = replicate population initStats | |
final = addStats initial (L.unpack lbs) | |
print $ map average final | |
{- | |
[127.436561,127.449141,127.64308,127.551385,127.479474,127.457795,127.577525,127.697076,127.463543] | |
1,046,425,584 bytes allocated in the heap | |
247,482,784 bytes copied during GC | |
83,160 bytes maximum residency (275 sample(s)) | |
193,920 bytes maximum slop | |
2 MB total memory in use (0 MB lost due to fragmentation) | |
Tot time (elapsed) Avg pause Max pause | |
Gen 0 1713 colls, 0 par 0.008s 0.120s 0.0001s 0.0009s | |
Gen 1 275 colls, 0 par 0.004s 0.013s 0.0000s 0.0002s | |
INIT time 0.000s ( 0.000s elapsed) | |
MUT time 0.008s ( 0.139s elapsed) | |
GC time 0.012s ( 0.133s elapsed) | |
EXIT time 0.000s ( 0.000s elapsed) | |
Total time 0.020s ( 0.272s elapsed) | |
%GC time 60.0% (48.7% elapsed) | |
Alloc rate 130,803,198,000 bytes per MUT second | |
Productivity 40.0% of total user, 2.9% of total elapsed | |
real 0m0.274s | |
user 0m0.020s | |
sys 0m0.252s | |
-} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE TemplateHaskell, TypeFamilies, MultiParamTypeClasses #-} | |
import qualified Data.ByteString.Lazy as L | |
import Data.Word (Word8) | |
import Data.Vector.Unboxed.Deriving | |
import qualified Data.Vector.Unboxed as V | |
import qualified Data.Vector.Unboxed.Mutable as M | |
import Control.Monad.Primitive (PrimState) | |
data Stats = Stats | |
{ total :: !Int | |
, count :: !Int | |
} | |
-- auto-generate the marshaling code | |
derivingUnbox "Stats" | |
[t|Stats -> (Int, Int)|] | |
[|\(Stats t c) -> (t, c)|] | |
[|\(t, c) -> Stats t c|] | |
initStats :: Stats | |
initStats = Stats 0 0 | |
addStat :: Int -> Stats -> Stats | |
addStat x (Stats t c) = Stats (t + x) (c + 1) | |
average :: Stats -> Double | |
average (Stats t c) = fromIntegral t / fromIntegral c | |
fileName :: FilePath | |
fileName = "sample-data.bin" | |
population :: Int | |
population = 9 | |
addStats :: M.MVector (PrimState IO) Stats -> [Word8] -> IO () | |
addStats m = | |
loop 0 | |
where | |
loop _ [] = return () | |
loop index bytes | index >= M.length m = loop 0 bytes | |
loop index (x:bytes) = do | |
stats <- M.unsafeRead m index | |
M.unsafeWrite m index $ addStat (fromIntegral x) stats | |
loop (index + 1) bytes | |
main :: IO () | |
main = do | |
lbs <- L.readFile "sample-data.bin" | |
m <- M.replicate population initStats | |
addStats m (L.unpack lbs) | |
final <- V.unsafeFreeze m | |
print $ V.map average final | |
{- | |
fromList [127.436561,127.449141,127.64308,127.551385,127.479474,127.457795,127.577525,127.697076,127.463543] | |
374,426,560 bytes allocated in the heap | |
148,927,200 bytes copied during GC | |
57,208 bytes maximum residency (138 sample(s)) | |
244,032 bytes maximum slop | |
3 MB total memory in use (0 MB lost due to fragmentation) | |
Tot time (elapsed) Avg pause Max pause | |
Gen 0 565 colls, 0 par 0.004s 0.075s 0.0001s 0.0010s | |
Gen 1 138 colls, 0 par 0.000s 0.006s 0.0000s 0.0002s | |
INIT time 0.000s ( 0.000s elapsed) | |
MUT time 0.004s ( 0.069s elapsed) | |
GC time 0.004s ( 0.081s elapsed) | |
EXIT time 0.000s ( 0.000s elapsed) | |
Total time 0.008s ( 0.150s elapsed) | |
%GC time 50.0% (54.0% elapsed) | |
Alloc rate 93,606,640,000 bytes per MUT second | |
Productivity 50.0% of total user, 2.7% of total elapsed | |
real 0m0.152s | |
user 0m0.008s | |
sys 0m0.140s | |
-} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment