[haskell] Haskell 데이터 유형의 메모리 공간

Haskell (대부분 GHC 사용)에 일부 데이터 유형의 값을 저장하는 데 필요한 실제 메모리 양을 어떻게 찾을 수 있습니까? 런타임시 (예 : GHCi에서) 평가할 수 있습니까? 아니면 구성 요소에서 복합 데이터 유형의 메모리 요구 사항을 추정 할 수 있습니까?

일반적 유형의 메모리 요구하는 경우 ab공지 같은 대수 데이터 유형의 메모리 오버 헤드는 무엇인가

data Uno = Uno a
data Due = Due a b

예를 들어, 이러한 값은 메모리에서 몇 바이트를 차지합니까?

1 :: Int8
1 :: Integer
2^100 :: Integer
\x -> x + 1
(1 :: Int8, 2 :: Int8)
[1] :: [Int8]
Just (1 :: Int8)
Nothing

지연된 가비지 수집으로 인해 실제 메모리 할당이 더 높다는 것을 알고 있습니다. 지연 평가로 인해 상당히 다를 수 있습니다 (그리고 썽크 크기는 값의 크기와 관련이 없습니다). 질문은 데이터 유형이 주어지면 그 값이 완전히 평가 될 때 얼마나 많은 메모리를 차지합니까?

:set +sGHCi에는 메모리 통계를 볼 수 있는 옵션이 있지만 단일 값의 메모리 사용량을 추정하는 방법은 명확하지 않습니다.



답변

(다음은 GHC에 적용되며 다른 컴파일러는 다른 저장소 규칙을 사용할 수 있습니다.)

경험 법칙 : 생성자는 헤더 당 한 단어, 각 필드 당 한 단어의 비용이 듭니다 . 예외 : 필드가없는 생성자 (예 : Nothing또는 True)는 공간을 차지하지 않습니다. GHC는 이러한 생성자의 단일 인스턴스를 만들고 모든 용도에서 공유하기 때문입니다.

워드는 32 비트 시스템에서 4 바이트이고 64 비트 시스템에서 8 바이트입니다.

그래서 예

data Uno = Uno a
data Due = Due a b

a Uno는 2 단어를 취하고 a Due는 3 단어를 취합니다.

Int타입으로 정의

data Int = I# Int#

이제 Int#한 단어를 사용하므로 Int총 2 개를 사용합니다. 대부분의 언 박싱 된 유형은 예외가되고, 하나의 말을 Int64#, Word64#그리고 Double#2 GHC 실제로 유형의 작은 값의 캐시가 가지고있는 (32 비트 시스템에서) Int하고 Char, 많은 경우에 이러한 전혀 힙 공간을 차지하지 않습니다. s> 255 String를 사용하지 않는 한 A 는 목록 셀을위한 공간 만 필요합니다 Char.

Int8동일한 표현을 갖는다 Int. Integer다음과 같이 정의됩니다.

data Integer
  = S# Int#                            -- small integers
  | J# Int# ByteArray#                 -- large integers

따라서 작은 Integer( S#)은 2 단어를 사용하지만 큰 정수는 값에 따라 가변적 인 공간을 차지합니다. A ByteArray#는 2 개의 단어 (헤더 + 크기)와 배열 자체를위한 공간을 사용합니다.

정의 된 생성자 newtype는 free 입니다. newtype순전히 컴파일 타임 아이디어이며 공간을 차지하지 않으며 런타임에 지침이 들지 않습니다.

자세한 내용 은 GHC 주석의 The Layout of Heap Objects를 참조하십시오 .


답변

ghc-datasize 패키지는 GHC 객체의 크기를 계산하는 recursiveSize 함수를 제공 합니다. 하나…

가비지 수집기는 힙 이동을 어렵게 만들기 때문에 크기가 계산되기 전에 가비지 수집이 수행됩니다.

… 그래서 이것을 자주 부르는 것은 실용적이지 않을 것입니다!

또한 데이터 유형에 대한 GHC의 메모리 표현을 찾는 방법을 참조하십시오 . 그리고 어떻게 하스켈 타입의 크기를 확인할 수 있습니까? .


답변