왜 GHC가 그렇게 큰가요?


147

간단한 대답이 있습니까? 왜 GHC가 그렇게 큰가요?

  • 오캠 : 2MB
  • 파이썬 : 15MB
  • SBCL : 9MB
  • OpenJRE-26MB
  • GHC : 113MB

"하스켈이 올바른 도구라면 왜 크기에 신경 쓰지 말아야합니까?"의 전도에는 관심이 없다. 이것은 기술적 인 질문입니다.


1
이 500MB를 어디서 얻습니까? 내 GHC는 그다지 크지 않습니다.
Jacob

당신이 모든 도서관을 세지 않는 한, 나는 추측한다 ...
Jacob

죄송합니다. 일부 dep가 포함 된 패키지 관리자 다운로드를 중단했습니다. 웹 사이트의 다운로드 크기를 반영하도록 업데이트했습니다. 편집 요약을 추가했지만 여기에 표시되지 않았습니다 (아직?). 나는 여전히 문제가 있다고 생각합니다. 그건 크다.
Christopher 완료

20
아마도 사과와 사과를 비교하고 오렌지와 오렌지를 비교해야 할 것입니다. JRE는 개발자 키트가 아닌 런타임입니다. OpenJDK 7 소스 번들, 82MB ( download.java.net/openjdk/jdk7 ) 대 GHC 7 소스 번들, 23MB ( haskell.org/ghc/download_ghc_7_0_1 ). 이제 런타임 : Ubuntu에서 openjdk-6-jre-headless, 77MB 비 압축 및 Haskell helloworld와 <1MB의 런타임과 정적으로 링크되었습니다.
sastanin

오늘 저는 2014 년 크기에 대해 궁금했습니다. URL을 찾았습니다 : 1.GHC haskell.org/ghc/download_ghc_7_8_3 ; 2. OpenJCK packages.ubuntu.com/precise/openjdk-7-jdk
AnneTheAgile

답변:


187

정말 어리석은 일입니다. GHC와 함께 제공되는 모든 라이브러리는 4 가지 맛으로 제공됩니다 .

  • 공전
  • 동적
  • 프로파일
  • GHCi

GHCi 버전은 단일 .o파일로 함께 연결된 정적 버전 입니다. 다른 세 버전은 모두 고유 한 인터페이스 파일 ( .hi파일) 세트를 가지고 있습니다. 프로파일 링 된 버전은 프로파일 링되지 않은 버전의 두 배 크기 인 것 같습니다.

기억 GHC 자체가 라이브러리 는 GHC의 4 개 복사본을 받고있어, 그래서. 뿐만 아니라 GHC 바이너리 자체는 정적으로 연결되어 있으므로 5 개의 GHC 사본이 있습니다.

우리는 최근에 GHCi가 정적 .a파일을 사용할 수 있도록 만들었습니다 . 그렇게하면이 맛들 중 하나를 제거 할 수 있습니다. 장기적으로는 GHC를 동적으로 연결해야하지만, C와 달리 기본값을 동적으로 연결하는 것이 수반되므로 GHC에서는 동적 연결 여부를 먼저 결정해야하기 때문에 더 큰 변화입니다. 그리고 이것이 실제로 실용되기 전에 더 많은 변경 (예 : Cabal 및 패키지 시스템 등)이 필요합니다.


16
그리고 나는 이것이 하스켈이 제공하는 모든 논리 인 게으른 평가, 타입 추론 등을 생각했습니다.
mcandre

4
따라서 113MB / 4 ~ = 28MB, 여전히 OpenJRE보다 큽니다. 그러나 GHC가 JRE뿐만 아니라 OpenJDK와 비교할 수 있다고 생각하면 기분이 좋아집니다.
어스 엔진

1
이제 GHC가 동적 연결을 사용한다고 생각할 것입니다. 아마도 @Simon Marlow의 4 가지 맛 압축에 대한 아이디어가 더 실용적입니까? 인용 : 1. # 3658 (GHCi를 지원하는 플랫폼에서 동적으로 GHCi 연결 (및 시스템 링커 사용)) – GHC ghc.haskell.org/trac/ghc/ticket/3658 ; 2. # 8266 (Mac에서의 동적 연결) – GHC ghc.haskell.org/trac/ghc/ticket/8266 ; GHC - # 8376 3. (? 정적 실행 + GHC API는 (+ 동적 링크는) segfault의 제공)
AnneTheAgile

56

아마도 사과와 사과를 비교하고 오렌지와 오렌지를 비교해야 할 것입니다. JRE는 개발자 키트가 아닌 런타임입니다. 개발 키트의 소스 크기, 컴파일 된 개발 키트의 크기 및 최소 런타임의 컴파일 된 크기를 비교할 수 있습니다.

OpenJDK 7 소스 번들은 82MB (download.java.net/openjdk/jdk7)와 GHC 7 소스 번들은 23MB (haskell.org/ghc/download_ghc_7_0_1)입니다. GHC는 크지 않습니다. 런타임 크기 : Ubuntu의 openjdk-6-jre-headless는 압축되지 않은 77MB이며 Haskell helloworld는 런타임과 정적으로 링크되어 있으며 <1MB입니다. GHC는 크지 않습니다.

GHC가 큰 경우 컴파일 된 개발 키트의 크기는 다음과 같습니다.

GHC 디스크 사용량

GHC 자체는 270MB를 차지하며 모든 라이브러리와 유틸리티는 500MB를 초과합니다. 그리고 기본 라이브러리와 빌드 도구 / 종속성 관리자조차도 많은 일입니다. Java 개발 플랫폼이 더 작습니다.

GHC :

$ aptitude show ghc6 | grep Size
Uncompressed Size: 388M

OpenJDK와의 종속성에 대한

$ aptitude show openjdk-6-jdk openjdk-6-jre openjdk-6-jre-headless ant maven2 ivy | grep Size
Uncompressed Size: 34.9M
Uncompressed Size: 905k
Uncompressed Size: 77.3M
Uncompressed Size: 1,585k
Uncompressed Size: 3,736k
Uncompressed Size: 991k

그러나 작성하는 동안 26MB가 아니라 여전히 100MB 이상입니다.

ghc6 및 ghc6-prof의 헤비급 항목은 다음과 같습니다.

$ dpkg -L ghc6 | grep '\.a$' | xargs ls -1ks | sort -k 1 -n -r | head -3
57048 /usr/lib/ghc-6.12.1/ghc-6.12.1/libHSghc-6.12.1.a
22668 /usr/lib/ghc-6.12.1/Cabal-1.8.0.2/libHSCabal-1.8.0.2.a
21468 /usr/lib/ghc-6.12.1/base-4.2.0.0/libHSbase-4.2.0.0.a
$ dpkg -L ghc6-prof | grep '\.a$' | xargs ls -1ks | sort -k 1 -n -r | head -3
112596 /usr/lib/ghc-6.12.1/ghc-6.12.1/libHSghc-6.12.1_p.a
 33536 /usr/lib/ghc-6.12.1/Cabal-1.8.0.2/libHSCabal-1.8.0.2_p.a
 31724 /usr/lib/ghc-6.12.1/base-4.2.0.0/libHSbase-4.2.0.0_p.a

얼마나 큰지 참고하십시오 libHSghc-6.12.1_p.a. 따라서 대답은 모든 라이브러리의 정적 링크 및 프로파일 링 버전 인 것 같습니다.


9

내 추측은-많은 정적 연결입니다. 각 라이브러리는 해당 종속성을 정적으로 연결해야하며, 그에 따라 종속성과 정적으로 연결해야합니다. 그리고 이것은 프로파일 링의 유무에 관계없이 종종 컴파일되며, 프로파일 링 없이도 바이너리는 제거되지 않으므로 많은 디버거 정보를 보유합니다.


2
GHC가 전체 프로그램으로 전환하고 jhc와 비슷한 거의 모든 모델을 다시 컴파일해도 상관 없습니다. 'ld'가 바뀌지 않으면 컴파일 속도가 더 빠를 수도 있습니다.
John L

8

gcc 와 많은 라이브러리를 번들로 제공하기 때문에 모두 정적으로 링크됩니다.

최소한 Windows에서는.


12
아니요, 리눅스가 아닙니다. gcc에만 의존합니다. 윈도우는 "배포"에 gcc가 없기 때문에 ghc와 함께 제공되어야합니다.
comonad

5

내 상자의 디렉토리 크기 분석은 다음과 같습니다.

https://spreadsheets.google.com/ccc?key=0AveoXImmNnZ6dDlQeHY2MmxPcEYzYkpweEtDSS1fUlE&hl=ko

가장 큰 디렉토리 (123MB)는 컴파일러 자체를 컴파일하기위한 바이너리입니다. 문서의 무게는 놀라운 65MB입니다. 3 위는 Cabal at 41 MB입니다.

bin 디렉토리는 33MB이며, 그 중 일부만 Haskell 응용 프로그램을 빌드하는 데 기술적으로 필요하다고 생각합니다.


6
이것에 뭔가를 추가하겠습니다 : 베어 본 컴파일러 만 가져 와서 절대적으로 필요하지 않은 것을 제거하면 (예 : 컴파일러를 프로파일 링하지 않고 제거하는 등) 약 5MB로 줄일 수 있습니다. 그러나 컴파일러 크기를 GCC와 비교하십시오. (댓글을 편집 했으므로 삭제해야했습니다 ... 죄송합니다)
fuz

5

짧은 대답은 모든 실행 파일이 정적으로 링크되어 있고 디버그 정보가 있고 라이브러리가 여러 사본에 포함되어 있기 때문입니다. 이것은 이미 다른 주석가들에 의해 언급되었습니다.

동적 연결이 가능하며 크기가 크게 줄어 듭니다. 예를 들면 다음과 같습니다 Hello.hs.

main = putStrLn "Hello world"

Windows에서 GHC 7.4.2로 빌드합니다.

ghc --make -O2Hello.exe1105K 제공

strip그것에 실행 630K 잎

ghc --make -O2 -dynamic 40K를 준다

스트립하면 13K 만 남습니다.

종속성은 5 dll이며 총 크기는 9.2MB이며, 5.7MB는 제거됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.