What are the spatial complexities of inits and tails?

TL DR

After reading an excerpt in Okasaki purely functional data structures and sorting through illustrative examples of singly linked lists (like Haskell lists do), I had to wonder about spatial complexity Data.List initsand tails...

I think that

  • spatial complexity tailsis linear in the length of the argument, and
  • spatial complexity is inits quadratic in the length of the argument,

but a simple test points to another.

Justification

From the tailssource list can be shared. The calculation tails xssimply consists in going through the list xsand creating a new pointer to each element of this list; no need to recreate the part xsin memory.

On the contrary, since each element inits xs"ends in a different way," there can be no such sharing, and all possible prefixes xsmust be recreated from scratch in memory.

Benchmark

The simple example shown below shows that the difference between the memory allocation between the two functions is small:

-- Main.hs

import Data.List (inits, tails)

main = do
    let intRange = [1 .. 10 ^ 4] :: [Int]
    print $ sum intRange
    print $ fInits intRange
    print $ fTails intRange

fInits :: [Int] -> Int
fInits = sum . map sum . inits

fTails :: [Int] -> Int
fTails = sum . map sum . tails

After compiling my file Main.hswith

ghc -prof -fprof-auto -O2 -rtsopts Main.hs

and working

./Main +RTS -p

The file Main.profreports the following:

COST CENTRE MODULE  %time %alloc

fInits      Main     60.1   64.9
fTails      Main     39.9   35.0

The memory allocated to fInitsand allocated to fTailshas the same order of magnitude ... Hum ...

What's happening?

  • tails () inits ()?
  • , GHC fInits fTails? - ?
  • ?
+4
1

inits Haskell, , 4.7.0.1 (GHC 7.8.3), . , fmap , .

inits [1,2,3,4] = [] : fmap (1:) (inits [2,3,4])
 = [] : fmap (1:) ([] : fmap (2:) (inits [3,4]))
 = [] : [1] : fmap (1:) (fmap (2:)) ([] : fmap (3:) (inits [4]))
....

, , take :

inits xs = [] : go (1 :: Int) xs where
  go !l (_:ls) = take l xs : go (l+1) ls
  go _  []     = []

Felgenhauer , , take, , .

:

inits = map reverse . scanl (flip (:)) []

(, map head . inits) . , , Chris Okasaki Banker, . , , scanl', scanl, GHC 7.8.4. inits O (n) ; O (n ^ 2) , conses . inits tails, Data.Sequence; . Data.Vector &mdash: .

+1

All Articles