Por que o GHC é tão grande / grande?

147

Existe uma resposta simples: por que o GHC é tão grande?

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

Não estou interessado no evangelismo de "Por que eu não deveria me importar com o tamanho, se Haskell é a ferramenta certa"; Esta é uma questão técnica.

Christopher Done
fonte
1
De onde você está tirando esses 500 MB? Meu GHC não está nem perto desse tamanho.
Jacob
A menos que você contar todas as bibliotecas, eu acho ...
Jacob
Desculpe, eu estava saindo de um download do gerenciador de pacotes que inclui alguns deps. Eu o atualizei para refletir o tamanho do download do site. Adicionei um resumo de edição, mas ele não apareceu aqui (ainda?). Eu acho que a pergunta ainda permanece. É grande.
Christopher Done
20
Provavelmente devemos comparar maçãs com maçãs e laranjas com laranjas. O JRE é um tempo de execução, não um kit de desenvolvedor. Pacote de código-fonte do OpenJDK 7, 82 MB ( download.java.net/openjdk/jdk7 ) vs pacote de código-fonte do GHC 7, 23 MB ( haskell.org/ghc/download_ghc_7_0_1 ). Agora em tempo de execução: openjdk-6-jre-headless no Ubuntu, 77 MB descompactado vs Haskell helloworld, vinculado estaticamente ao tempo de execução, <1 MB.
Sastanin
Hoje fiquei curioso sobre os tamanhos agora em 2014. Parece que o argumento ainda se mantém. Eu encontrei URLS: 1.GHC haskell.org/ghc/download_ghc_7_8_3 ; 2.OpenJCK packages.ubuntu.com/precise/openjdk-7-jdk
AnneTheAgile

Respostas:

187

É um pouco bobo realmente. Cada biblioteca que acompanha o GHC é fornecida em nada menos que 4 tipos :

  • estático
  • dinâmico
  • perfilado
  • GHCi

A versão do GHCi é apenas a versão estática vinculada em um único .oarquivo. As outras três versões também possuem seu próprio conjunto de arquivos de interface ( .hiarquivos). As versões com perfil parecem ter aproximadamente o dobro do tamanho das versões sem perfil (o que é um pouco suspeito, eu deveria examinar o motivo).

Lembre-se de que o próprio GHC é uma biblioteca , então você está recebendo 4 cópias do GHC. Não apenas isso, mas o próprio binário do GHC está estaticamente vinculado, então são 5 cópias do GHC.

Recentemente, fizemos para que o GHCi pudesse usar os .aarquivos estáticos . Isso nos permitirá livrar-se de um desses sabores. A longo prazo, devemos vincular dinamicamente o GHC, mas essa é uma mudança maior, porque isso implicaria em tornar o vínculo dinâmico o padrão - ao contrário de C, com o GHC, você precisa decidir antecipadamente se deseja vincular dinamicamente ou não. E precisamos de mais mudanças (por exemplo, no Cabal e no sistema de pacotes, entre outras coisas) antes que isso seja realmente prático.

Simon Marlow
fonte
16
E aqui eu pensei que era toda a lógica que oferece Haskell: avaliação preguiçoso, tipo de inferência, etc.
mcandre
4
Então, 113MB / 4 ~ = 28MB, ainda maior que o OpenJRE ... Mas considere o GHC comparável ao OpenJDK, não apenas ao JRE, isso me faz sentir melhor.
Earth Engine
1
Agora que acho que o GHC usa ligação dinâmica, talvez as idéias do Dr. @ Simon Marlow para a compressão dos quatro sabores sejam mais práticas? Cita: 1. # 3658 (Vincule dinamicamente o GHCi (e use o vinculador do sistema) nas plataformas que o suportam) - GHC ghc.haskell.org/trac/ghc/ticket/3658 ; 2. # 8266 (Link dinâmico no Mac) - GHC ghc.haskell.org/trac/ghc/ticket/8266 ; 3. # 8376 (Executável estático + API do GHC (+ vínculo dinâmico?) Fornece Segfault)
#
56

Provavelmente devemos comparar maçãs com maçãs e laranjas com laranjas. O JRE é um tempo de execução, não um kit de desenvolvedor. Podemos comparar: tamanho da fonte do kit de desenvolvimento, o tamanho do kit de desenvolvimento compilado e o tamanho compilado do tempo de execução mínimo.

O pacote configurável de origem do OpenJDK 7 tem 82 MB (download.java.net/openjdk/jdk7) versus o pacote configurável de origem GHC 7, que possui 23 MB (haskell.org/ghc/download_ghc_7_0_1). O GHC não é grande aqui. Tamanho do tempo de execução: openjdk-6-jre-headless no Ubuntu tem 77 MB descompactado vs Haskell helloworld, vinculado estaticamente ao tempo de execução, que é <1 MB. O GHC não é grande aqui.

Onde o GHC é grande, é o tamanho do kit de desenvolvimento compilado:

Uso do disco GHC

O próprio GHC ocupa 270 MB e, com todas as bibliotecas e utilitários que se reúnem, ocupa mais de 500 MB. E sim, é muito, mesmo com bibliotecas de base e um gerenciador de ferramentas / dependências de construção. A plataforma de desenvolvimento Java é menor.

GHC:

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

contra o OpenJDK com dependências:

$ 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

Mas ainda tem mais de 100 MB, e não 26 MB enquanto você escreve.

Os itens pesados ​​em ghc6 e ghc6-prof são:

$ 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

Por favor, note o quão grande é libHSghc-6.12.1_p.a. Portanto, a resposta parece ser a versão estática de links e perfis para todas as bibliotecas existentes.

sastanina
fonte
9

Meu palpite - muitos e muitos links estáticos. Cada biblioteca precisa vincular estaticamente suas dependências, as quais, por sua vez, precisam vincular estaticamente as suas e as suas propriedades. E tudo isso é compilado frequentemente com e sem criação de perfil, e mesmo sem criação de perfil, os binários não são removidos e, portanto, mantêm muitas informações do depurador.

sclv
fonte
2
Eu provavelmente não me importaria se o GHC mudasse para um programa inteiro, recompile quase tudo o modelo, semelhante ao jhc. Pode até compilar mais rápido se impedir que o 'ld' seja trocado.
John L
8

Porque inclui o gcc e um monte de bibliotecas, todas vinculadas estaticamente.

Pelo menos no Windows.

Marko
fonte
12
não, não no linux. isso depende apenas do gcc. porque o windows não possui gcc em sua "distribuição", ele tem que vir com o ghc.
comonad 15/02
5

Aqui está o detalhamento do tamanho do diretório na minha caixa:

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

Parece que o maior diretório (123 MB) são os binários para compilar o próprio compilador. Os documentos pesam surpreendentes 65 MB. O terceiro lugar é Cabal, com 41 MB.

O diretório bin tem 33 MB e acho que apenas um subconjunto é o que é tecnicamente necessário para criar aplicativos Haskell.

Jacob
fonte
6
Deixe-me acrescentar algo a isso: Se você pegar o compilador barebone e remover tudo o que não for absolutamente necessário (como compilar o compilador sem perfil, sem strip etc.), poderá reduzir para cerca de 5 MB. Mas tente comparar o tamanho dos compiladores com o GCC. (Editado o comentário, então eu tive que excluí-lo ... desculpe) #
01/02/11
5

A resposta curta é que todos os executáveis ​​estão vinculados estaticamente, podem ter informações de depuração e as bibliotecas estão incluídas em várias cópias. Isso já foi dito por outros comentaristas.

A ligação dinâmica é possível e reduzirá drasticamente o tamanho. Aqui está um exemplo Hello.hs:

main = putStrLn "Hello world"

Eu construo com o GHC 7.4.2 no Windows.

ghc --make -O2Hello.exede 1105Ks

Correndo stripsobre ele deixa 630K

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

Descascar deixa apenas 13K.

Suas dependências são 5 dlls, com tamanho total de 9,2 MB sem remoção e 5,7 MB com remoção.

nponeccop
fonte