[haskell] 왜 GHC가 그렇게 큰가요?

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

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

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



답변

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

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

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

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

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


답변

아마도 사과와 사과를 비교하고 오렌지와 오렌지를 비교해야 할 것입니다. 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. 따라서 대답은 모든 라이브러리의 정적 링크 및 프로파일 링 버전 인 것 같습니다.


답변

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


답변

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

최소한 Windows에서는.


답변

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

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

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

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


답변

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

동적 연결이 가능하며 크기가 크게 줄어 듭니다. 예를 들면 다음과 같습니다 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는 제거됩니다.


답변