문제

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

일반적으로 유형의 메모리 요구 사항이 a 그리고 b 다음과 같은 대수 데이터 유형의 메모리 오버헤드는 무엇입니까?

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 +s GHCi의 옵션을 사용하여 메모리 통계를 볼 수 있지만 단일 값의 메모리 사용 공간을 추정하는 방법은 명확하지 않습니다.

도움이 되었습니까?

해결책

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

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

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

예를 들어

data Uno = Uno a
data Due = Due a b

Uno 2개의 단어를 취하고, Due 3이 걸립니다.

그만큼 Int 유형은 다음과 같이 정의됩니다.

data Int = I# Int#

지금, Int# 한 단어를 취합니다. Int 총 2개 걸립니다.대부분의 unboxed 유형은 한 단어를 사용합니다. 예외는 다음과 같습니다. Int64#, Word64#, 그리고 Double# (32비트 시스템에서는) 2개를 사용합니다.GHC에는 실제로 유형의 작은 값 캐시가 있습니다. Int 그리고 Char, 따라서 많은 경우 힙 공간을 전혀 차지하지 않습니다.ㅏ String 다음을 사용하지 않는 한 목록 셀을 위한 공간만 필요합니다. Chars > 255.

Int8 와 동일한 표현이 있습니다. Int. Integer 다음과 같이 정의됩니다.

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

그래서 작은 Integer (S#)은 2단어를 사용하지만 큰 정수는 값에 따라 다양한 공간을 차지합니다.ㅏ ByteArray# 2단어(헤더 + 크기)와 배열 자체를 위한 공간이 필요합니다.

참고하세요 다음으로 정의된 생성자 newtype 무료입니다. newtype 순전히 컴파일 타임 아이디어이며 공간을 차지하지 않으며 런타임 시 명령 비용도 들지 않습니다.

자세한 내용은 GHC 주석의 힙 개체 레이아웃.

다른 팁

ghc-datasize 패키지는 다음을 제공합니다. 재귀 크기 GHC 객체의 크기를 계산하는 함수입니다.하지만...

쓰레기 수집기가 힙 보행을 어렵게 만들기 때문에 크기가 계산되기 전에 쓰레기 수집이 수행됩니다.

...그래서 자주 호출하는 것은 실용적이지 않습니다!

또한 참조하십시오 데이터 유형에 대한 GHC의 메모리 표현을 찾는 방법은 무엇입니까? 그리고 Haskell에서 유형의 크기를 어떻게 결정할 수 있나요?.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top