Я определяю свою собственную версию concat
, myConcat
:
module Eh where
myConcat [] = []
myConcat ([]:os) = myConcat os
myConcat ((x:xs):os) = x : myConcat (xs:os)
(!!!) :: [a] -> Int -> a
xs !!! n | n < 0 = error "negative index"
[] !!! _ = error "index too large"
(x:_) !!! 0 = x
(_:xs) !!! n = xs !!! (n-1)
Если я делаю myConcat <какой-то огромный список> !!! n
в интерпретаторе GHC, он крадет мою память со скоростью 300MB/s, и я должен убить его, прежде чем он сможет вызвать OOM killer. Обратите внимание, что я загружаю Eh
как "интерпретируемый", я не компилирую его перед загрузкой.
code run in the GHC interpreter space leak? myConcat (repeat [1,2,3,4]) !! (10^8) Yes concat (repeat [1,2,3,4]) !! (10^8) No myConcat (repeat [1,2,3,4]) !!! (10^8) No concat (repeat [1,2,3,4]) !!! (10^8) No
Теперь, если я скомпилирую Eh
(ghc --make -O2 Eh.hs
), а затем загружу его в интерпретатор и снова запущу эти тесты, ни один из них не пропустит пробел. То же самое, если я компилирую каждый тест вместо того, чтобы запускать их в интерпретаторе.
Что происходит?
Я запускаю GHC 6.12.3.