Evaluation of higher order functions

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. enter image description here 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

, , , : enter image description here , , (25000 ): enter image description here , -, . , 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 install
  • laziness myfile.wav +RTS -hy.
  • pdf hp2ps ps2pdf.

, I:

  • cd laziness/src
  • ghc Main.hs -O2 -rtsopts -prof.
  • ./Main myfile.wav +RTS -hy.
  • pdf hp2ps ps2pdf.

, , , cabal. . cabal?

+4

:

3

:

550
?
363
?
110
?
26
?
10
-
3

Source: https://habr.com/ru/post/1670232/


All Articles