I wrote a function getSamplesFromFilethat takes a file and returns its contents as Vectorfrom Floats. The functions read the contents of the file into Data.ByteStringwith Data.ByteString.hGet, then convert this Data.ByteStringto Vectorfrom Floats, using:
import qualified Data.Vector.Unboxed as V
import qualified Data.ByteString as BS
import Data.Word
import System.Environment
import GHC.Int
toVector :: BS.ByteString -> V.Vector Float
toVector bs = vgenerate (fromIntegral (BS.length bs `div` 3)) $ \i ->
myToFloat [BS.index bs (3*i), BS.index bs (3*i+1), BS.index bs (3*i+2)]
where
myToFloat :: [Word8] -> Float
myToFloat = sum . map fromIntegral
vgenerate n f = V.generate n (f . fromIntegral)
I tested how this program was lazy with a small test program:
main = do
[file] <- getArgs
samples <- getSamplesFromFile file
let slice = V.slice 0 50000 samples
print slice
If I run this in a 13 MB file, it seems that each sample is loaded into memory, although I only need 50,000 samples to print.
If I make a small modification to this problem and first map or filter it, the result will be different:
main = do
[file] <- getArgs
samples <- getSamplesFromFile file
let slice = V.slice 0 50000 samples
let mapped = V.map id slice
print mapped
, , , :
, , (25000 ):
, -, . , id.
. , ?
, - cabal. , cabal, . , Main.hs cabal. Main.hs :
module Main where
import qualified Data.ByteString as BS
import qualified Data.Vector.Unboxed as V
import Data.Word
import GHC.Int
import System.Environment
main = do
[file] <- getArgs
samples <- getSamplesFromFile file
let slice = V.slice 0 50000 samples
--let filtered = V.filter (>0) slice
let mapped = V.map id slice
print slice
getSamplesFromFile = fmap toVector . BS.readFile
toVector :: BS.ByteString -> V.Vector Float
toVector bs = vgenerate (fromIntegral (BS.length bs `div` 3)) $ \i ->
myToFloat [BS.index bs (3*i), BS.index bs (3*i+1), BS.index bs (3*i+2)]
where
myToFloat :: [Word8] -> Float
myToFloat = sum . map fromIntegral
vgenerate n f = V.generate n (f . fromIntegral)
, :
- -
mkdir Main.hs .ghc Main.hs -O2 -rtsopts -prof../Main myfile.wav +RTS -hy.- pdf
hp2ps ps2pdf.
, :
- , ,
mkdir laziness. cabal cabal init.Main.hs /src.ghc-options: -O2 -rtsopts -prof laziness.cabal.cabal installlaziness myfile.wav +RTS -hy.- pdf
hp2ps ps2pdf.
, I:
cd laziness/srcghc Main.hs -O2 -rtsopts -prof../Main myfile.wav +RTS -hy.- pdf
hp2ps ps2pdf.
, , , cabal. . cabal?