Perché GHC è così grande / grande?


147

C'è una risposta semplice: perché GHC è così grande?

  • OCaml: 2 MB
  • Python: 15 MB
  • SBCL: 9 MB
  • OpenJRE - 26 MB
  • GHC: 113 MB

Non mi interessa l'evangelizzazione di "Perché non dovrei preoccuparmi delle dimensioni se Haskell è lo strumento giusto"; questa è una domanda tecnica.


1
Da dove prendi questo 500MB? Il mio GHC non è affatto vicino a quello grande.
Jacob,

A meno che non conti tutte le biblioteche, immagino ...
Jacob,

Mi dispiace, stavo per scaricare un download del gestore pacchetti che include alcuni deps. L'ho aggiornato per riflettere le dimensioni del download dal sito web. Ho aggiunto un riepilogo di modifica ma non è stato visualizzato qui (ancora?). Penso che la domanda sia ancora valida. È grande.
Christopher Fatto l'

20
Probabilmente dovremmo confrontare le mele con le mele e le arance con le arance. JRE è un runtime, non un kit di sviluppo. Bundle sorgente OpenJDK 7, 82 MB ( download.java.net/openjdk/jdk7 ) vs bundle sorgente GHC 7, 23 MB ( haskell.org/ghc/download_ghc_7_0_1 ). Ora runtime: openjdk-6-jre-headless su Ubuntu, 77 MB non compresso vs Haskell helloworld, staticamente collegato con il suo runtime, <1 MB.
sastanin,

Oggi ero curioso delle dimensioni ora 2014. Sembra che l'argomento sia ancora valido. Ho trovato gli URL: 1.GHC haskell.org/ghc/download_ghc_7_8_3 ; 2.ApriJCK pacchetti.ubuntu.com/precise/openjdk-7-jdk
AnneTheAgile

Risposte:


187

È un po 'sciocco davvero. Ogni libreria fornita con GHC è fornita in non meno di 4 versioni :

  • statico
  • dinamico
  • profilato
  • GHCi

La versione GHCi è solo la versione statica collegata insieme in un singolo .ofile. Le altre tre versioni hanno tutte il proprio set di file di interfaccia ( .hifile). Le versioni profilate sembrano essere circa il doppio delle versioni non profilate (il che è un po 'sospetto, dovrei esaminare il perché).

Ricorda che GHC stesso è una libreria , quindi otterrai 4 copie di GHC. Non solo, ma lo stesso binario GHC è staticamente collegato, quindi sono 5 copie di GHC.

Di recente ce l'abbiamo fatta in modo che GHCi potesse usare i .afile statici . Questo ci permetterà di sbarazzarci di uno di questi sapori. A più lungo termine, dovremmo collegare dinamicamente GHC, ma questo è un cambiamento più grande perché ciò comporterebbe il collegamento dinamico di default - a differenza di C, con GHC devi decidere in anticipo se vuoi collegarti dinamicamente o no. E abbiamo bisogno di più cambiamenti (ad esempio Cabal e il sistema di pacchetti, tra le altre cose) prima che ciò sia veramente pratico.


16
E qui ho pensato che fosse tutta la logica che Haskell offre: valutazione pigra, inferenza di tipo, ecc.
mcandre

4
Quindi, 113 MB / 4 ~ = 28 MB, ancora più grande di OpenJRE ... Ma considerare GHC è paragonabile a OpenJDK, non solo a JRE, mi fa sentire meglio.
Earth Engine,

1
Ora che penso che GHC utilizzi il collegamento dinamico, forse le idee del Dr. @Simon Marlow per la compressione dei quattro sapori sono più pratiche? Cita: 1. # 3658 (collega dinamicamente GHCi (e usa il linker di sistema) su piattaforme che lo supportano) - GHC ghc.haskell.org/trac/ghc/ticket/3658 ; 2. # 8266 (collegamento dinamico su Mac) - GHC ghc.haskell.org/trac/ghc/ticket/8266 ; 3. # 8376 (eseguibile statico + API GHC (+ Dynamic Linking?) Dà Segfault) - GHC
AnneTheAgile

56

Probabilmente dovremmo confrontare le mele con le mele e le arance con le arance. JRE è un runtime, non un kit di sviluppo. Possiamo confrontare: dimensione della sorgente del kit di sviluppo, dimensione del kit di sviluppo compilato e dimensione compilata del tempo di esecuzione minimo.

Il pacchetto sorgente OpenJDK 7 è 82 MB (download.java.net/openjdk/jdk7) rispetto al pacchetto sorgente GHC 7, che è 23 MB (haskell.org/ghc/download_ghc_7_0_1). GHC non è grande qui. Dimensioni di runtime: openjdk-6-jre-headless su Ubuntu è 77 MB non compresso vs Haskell helloworld, staticamente collegato con il suo runtime, che è <1 MB. GHC non è grande qui.

Dove GHC è grande, è la dimensione del kit di sviluppo compilato:

Utilizzo del disco GHC

GHC stesso richiede 270 MB e con tutte le librerie e le utility che si uniscono ne superano i 500 MB. E sì, è molto, anche con le librerie di base e uno strumento di compilazione / gestore delle dipendenze. La piattaforma di sviluppo Java è più piccola.

GHC:

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

contro OpenJDK con dipendenze:

$ 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

Ma è ancora più di 100 MB, non 26 MB mentre scrivi.

Le cose pesanti in ghc6 e ghc6-prof sono:

$ 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

Nota quanto è grande libHSghc-6.12.1_p.a. Quindi la risposta sembra essere il collegamento statico e le versioni di profiling per ogni libreria là fuori.


9

La mia ipotesi - un sacco di collegamenti statici. Ogni biblioteca ha bisogno di collegare staticamente le sue dipendenze, che a loro volta devono collegare staticamente loro e soforth. E questo è tutto compilato spesso sia con che senza profiling, e anche senza profiling i binari non sono spogliati e quindi contengono molte informazioni di debugger.


2
Probabilmente non mi dispiacerebbe se GHC passasse a un intero programma, ricompilasse quasi tutto il modello, simile a jhc. Potrebbe anche compilare più velocemente se impedirebbe a "ld" di scambiarsi.
John L

8

Perché raggruppa gcc e un mucchio di librerie, tutte collegate staticamente.

Almeno su Windows.


12
no, non su linux. dipende solo da gcc. poiché windows non ha gcc nella sua "distribuzione", deve venire con ghc.
comonad,

5

Ecco la suddivisione della dimensione della directory sulla mia scatola:

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

Sembra che la directory più grande (123 MB) sia i file binari per la compilazione del compilatore stesso. I documenti hanno un peso sorprendente di 65 MB. Il terzo posto è Cabal a 41 MB.

La directory bin è di 33 MB e penso che solo un sottoinsieme di ciò sia ciò che è tecnicamente necessario per creare applicazioni Haskell.


6
Consentitemi di aggiungere qualcosa a questo: se prendete solo il compilatore barebone e togliete tutto ciò che non è assolutamente necessario (come costruire il compilatore non profilato, stripped ecc.), Potete scendere a circa 5 MB. Ma prova a confrontare le dimensioni dei compilatori con GCC. (Ho modificato il commento, quindi ho dovuto cancellarlo ... scusate)
fuz

5

La risposta breve è perché tutti i file eseguibili sono collegati staticamente, possono contenere informazioni di debug e le librerie sono incluse in più copie. Questo è già stato detto da altri commentatori.

Il collegamento dinamico è possibile e ridurrà drasticamente le dimensioni. Ecco un esempio Hello.hs:

main = putStrLn "Hello world"

Costruisco con GHC 7.4.2 su Windows.

ghc --make -O2Hello.exedi 1105Ks

Correre stripsu di esso lascia 630K

ghc --make -O2 -dynamic dà 40K

Spogliandolo lascia solo 13K.

Le sue dipendenze sono 5 dll con una dimensione totale di 9,2 MB non eliminati e 5,7 MB eliminati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.