Por que CIL e CLR são necessários no .NET?

11

Eu vi essa imagem legal aqui . Aprendi que todos os compiladores que suportam a linguagem .net convertem o código-fonte em CILformato. Agora, a Microsoft nunca está trazendo .NETpara todo o sistema operacional escrevendo um CLR para todos os sistemas operacionais. Então, por que manter um formato de código intermediário e um CLR para executar esse CIL. Isso não é uma dor de cabeça para lidar. Por que a Microsoft escolheu ser assim?

EDITAR Essa arquitetura meio tem seu preço. Isso reduzirá o desempenho, não é? O Java faz isso para manter a independência da plataforma, por que motivo o .NET faz isso? Por que não manter um C simples e simples como o compilador? De qualquer maneira, também será necessário um compilador para converter o código em CIL, se eu precisar adicionar um novo idioma, a única diferença que ele faria é o idioma de destino. Tat é tudo.

vikkyhacks
fonte
3
Porque é mais fácil escrever compiladores no CIL. E é mais fácil escrever um CIL no compilador nativo do que um compilador em cada idioma no nativo.
Oded
9
@ratchetfreak: que pode ser uma razão para MS por não portar o CLR para outras plataformas, mas não é uma razão para ter um CLR, em primeiro lugar (que faz realmente uma porta mais fácil , para que o seu som argumento apenas como MS contusão,
Doc Brown
12
Também votou para 'M $', o que é isso, 1998?
Alan B
3
Eric Lippert discute isso (começando no terceiro parágrafo; os dois primeiros parágrafos são sobre Roslyn). A resposta curta é que o comentário de Oded e a resposta de Telastyn estão certos; você precisa codificar apenas os compiladores <Número de sistemas operacionais> + <Número de idiomas> em vez de compiladores <Número de sistemas operacionais> * <Número de idiomas>.
Brian
3
@busy_wait: a página referenciada menciona algumas desvantagens. Por exemplo, "as informações de configuração em dois aplicativos podem resultar em decisões de ligação diferentes para o mesmo assembly dependente". Gerar rapidamente evita esses problemas. Isso implica que a compilação realmente precisa ser feita após a distribuição do aplicativo (e, de fato, o NGEN deve ser executado em cada máquina de destino; não pode ser executado pelo distribuidor).
Brian

Respostas:

29

Porque eles só precisam escrever um compilador para C # no CIL - que é a parte mais difícil. Criar um intérprete (ou mais frequentemente, compilador Just-In-Time) para o CIL por plataforma é relativamente fácil comparado à gravação de um compilador do código C # para (por plataforma) executável.

Além disso, o tempo de execução pode lidar com qualquer coisa que seja compilada no CIL. Se você deseja um novo idioma (como F #), basta escrever um compilador para ele e obter automaticamente todo o suporte da plataforma para as coisas que o .NET suporta.

Ah, e eu posso pegar uma dll .NET e executá-la no Windows ou no Linux via Mono sem recompilação (supondo que todas as minhas dependências sejam satisfeitas).

Quanto ao desempenho, é discutível. Existem "pré-compiladores" essencialmente que pegam o CIL e fazem binários nativos. Outros argumentam que os compiladores just-in-time podem fazer otimizações que os compiladores estáticos simplesmente não podem. Na minha experiência, isso depende muito do que seu aplicativo está fazendo e em qual plataforma você está executando (principalmente o quão bom é o JITer nessa plataforma). É extremamente raro encontrar um cenário em que o .NET não seja bom o suficiente .

Telastyn
fonte
"intérprete" `? Eu pensei que sempre MS fornece apenas um JITter?
Doc Brown
1
@DocBrown - eh, sim - nome impróprio da minha parte. Fixação.
Telastyn 23/09
+1, você pode adicionar até um pouco de explicação para a minha edição para que eu possa aceitar essa resposta
vikkyhacks
Os tempos de execução de alto desempenho geralmente combinam um intérprete e um compilador JIT (execução em modo misto). Não tenho certeza sobre o .NET, mas muitas Java VMs usam essa abordagem.
Cyanfish
2
@busy_wait: Todo o tipo de coisas. Método inlining, propagação de cópias, remoção de código desnecessário, conversão de multiplicações / divisões em turnos, outras operações aritméticas usando readonlycampos. Os compiladores tradicionais podem fazer algumas dessas otimizações, mas somente quando elas podem ser detectadas pela análise estática. Por outro lado, um tremor pode descobrir em tempo de execução que (por exemplo) uma seção de código não está fazendo nenhum trabalho útil porque os objetos ou variáveis ​​que ele modifica não são referenciados em nenhum outro lugar. Não sou especialista em nervosismo, mas é basicamente uma questão do poder da análise dinâmica versus estática.
Aaronaught
14

O .NET possui uma linguagem intermediária (CIL / MSIL) e implementações específicas da plataforma de um CLR (Platform-Independent Runtime) pela mesma razão que Java. A Microsoft pretendia que o C # competisse diretamente com Java, e isso acontece nos sistemas operacionais que a Microsoft visa (próprios).

As vantagens, mesmo que o .NET seja suportado apenas nas plataformas Windows (ou em outros SOs que possuam um .NET semelhante ao Mono / Linux), são semelhantes ao Java:

  • Tempo de execução de memória gerenciada - Ao contrário de C / C ++ não gerenciado, os desenvolvedores de C # / VB.NET não precisam se preocupar em controlar estritamente a vida útil do objeto. Como Java, o CLR possui um coletor de lixo que libera automaticamente objetos na pilha que deixam o escopo. Embora isso possa parecer menor para alguém acostumado a tempos de execução não gerenciados, ele tem a vantagem secundária extrema de desencorajar a "magia negra" da aritmética dos ponteiros, tão comum no C / C ++.
  • Independência da plataforma - Windows Vista e Windows 7 funcionam de maneira diferente do Windows XP. O Windows 8 ainda funciona de maneira diferente. As versões do Windows Mobile, incluindo o Windows 8 Mobile, funcionam de maneira diferente novamente. Hardware diferente, arquitetura diferente, recursos diferentes. Embora o ambiente de destino ainda importe para um desenvolvedor .NET, a quantidade de conhecimento especializado é muito reduzida em comparação ao que é conhecido para criar um programa C / C ++ compatível para todos esses sistemas operacionais. O AC # dev ganha muito mais de graça.
  • Suporte a aplicativos da Web - ainda não vi um aplicativo da Web com script do servidor e voltado para o cliente, escrito desde o início em C ++. O servidor da Web , claro, Apache, ISS, todos eles normalmente são executados em um tempo de execução não gerenciado por motivos de velocidade / eficiência. No entanto, C ++ não é uma linguagem usada para criar aplicativos da Web. C # é (como é Java). Foi desenvolvido desde o início para suportar a próxima geração do paradigma ASP da Microsoft. Este é um código projetado para ser executado em uma sandbox; qual sandbox (o plug-in do ASP.NET para o ISS ou o CLR "desktop") é relativamente sem importância.
  • Independência de idioma / tempo de execução - Um compilador C ++ pega o código-fonte C ++ e produz código de montagem para uma arquitetura de processador usando uma linguagem de máquina. Para suportar uma arquitetura diferente e / ou linguagem de máquina, um compilador completamente novo deve ser gravado (e um conjunto completamente novo de bibliotecas de tempo de execução deve ser compilado). O compilador AC # pega o código-fonte C # e produz o CIL, que o JITer específico do hardware converte em código de máquina. O mesmo JITer pode traduzir qualquer programa CIL, independentemente do idioma de origem (e existem vários; C #, VB.NET, F # e uma série de portas de idioma "Iron", como IronHaskell, IronRuby, IronLisp, etc.). O mesmo compilador pode transformar um idioma no CIL que qualquer JITer pode executar, independentemente do hardware.
  • Concentre-se no código "correto" - Para os desenvolvedores do C ++, existem muitas maneiras "certas" de fazer algo, dependendo do que é mais importante; eficiência de memória, eficiência de CPU, independência de hardware, independência de SO etc. O código pode parecer drasticamente diferente quando cada uma delas é a prioridade. O C # foi projetado por um grupo que levou a sério as lições conceituais de Fowler e seus colegas (que estavam trabalhando para reformar o design de código na comunidade C ++, ensinando princípios orientados a objetos para uma comunidade que em grande parte se mudou para C a partir de C), como bem como as lições práticas aprendidas pelas linguagens anteriores (incluindo Java e sua obediência quase fanática ao Todo-Poderoso Objeto, quando um bom e velho ponteiro de função no estilo C ++ faria o trabalho com muito mais clareza e não menos objeto. orientado).

Por motivos antitruste, a MS toma cuidado para não ser vista "interferindo" demais em outras plataformas importantes como Android, Mac OSX / iOS e Linux; no entanto, ele realmente tem equipes em desenvolvimento para as três plataformas. Existe uma versão desenvolvida pelo MS do Office para OSX, existem vários aplicativos, incluindo aplicativos de interoperabilidade do Office para iOS e Android, o Skype (agora um produto da Microsoft) é executado no Linux, e a Microsoft até contribuiu para o kernel do Linux (principalmente em um mentalidade de virtualização).

KeithS
fonte
1
"Ainda não vi um aplicativo Web com script do servidor, voltado para o cliente, escrito desde o início em C ++." - onde você coloca CGIs de dias atrás? Minhas primeiras aplicações web (por mais triviais que fossem) eram 100% C. Naquela época (meados dos anos 90) era mais fácil escrever um .c e .h para fazer o trabalho padrão em cgi (as linguagens de 'script' eram apenas emergindo em cena também).
hm ... CGI, CGI ... Eu acho que eu ouvi dele, mas estou com Keith, estou ainda para realmente ver um :)
DXM
@DXM, o antigo modelo de conteúdo dinâmico era para o servidor da Web dividir um processo e colocar as coisas em locais padrão (parâmetros de consulta e similares em variáveis ​​de ambiente específicas) - a Common Gateway Interface. A saída desse processo foi então enviada de volta como o conteúdo. Antigamente, era mais fácil encontrar um programador que conhecia C ou C ++ do que perl ou python (e sh era muito desajeitado para esse trabalho).
1
Não subestime a importância da semelhança com Java. A Sun havia acabado de processar a MS pelo porto da JVM e ganhou alguns pontos legais (estupidamente, IMHO). O CIL e o CLR são inspirados por isso, e você notará que o J # é o mais próximo possível do Java sem desencadear outras ações legais. Uma grande diferença é que o CLR é independente da linguagem. Você realmente pode escrever um programa em uma mistura de C #, F # e J #, se for necessário. Apenas tente misturar Java com bibliotecas em outras linguagens e obtenha um programa estável.
RBerteig
1
Mas a interoperabilidade entre o MSIL e o código nativo é razoavelmente bem definida e simplesmente funciona. E, aparentemente, era esperado que funcionasse apenas por design e pelas atitudes da comunidade de usuários.
RBerteig
12

O sistema operacional Windows está disponível para diferentes tipos de CPU, hoje principalmente x64, x86, Intel, ARM.

O CIL / CLR é independente dessa plataforma de hardware - essas diferenças são "abstraídas" pelo ambiente de execução da IL. Por exemplo, um assembly .NET compilado para "qualquer CPU" geralmente pode ser executado no Win64 como um processo de 64 bits e no Win32 como um processo de 32 bits, sem a necessidade de fornecer executáveis ​​diferentes.

Além disso, o CIL permite que os metadados sejam armazenados em assemblies, o que não é possível com DLLs nativas (é possível, é claro, que a MS tenha feito isso antes com componentes COM, mas essa tecnologia nunca foi tão fácil de manusear quanto os componentes .NET). Isso facilita muito a criação de componentes de software e é a base da reflexão / introspecção em todas as linguagens .NET.

Doc Brown
fonte
Só para acrescentar um pouco a isso, eles não apenas permitem tipos de CPU diferentes, mas também versões diferentes (Core i3 / i5 / i7) e fornecedores (Intel vs. AMD) dentro do mesmo tipo de CPU (todos x64, por exemplo) podem ter diferentes conjuntos de instruções de montagem, que compilador JIT seria capaz de tirar proveito off
DXM
2
@ DXM: e você sabe o JIT realmente? Ou isso é mais uma coisa hipotética?
Doc Brown
Pelo menos um blog do MSDN afirma que o compilador JIT faz isso (ou fez, 8 anos atrás).
@DocBrown: Obviamente não tenho nenhum material de referência em mãos, mas pensei que me lembrava de ter lido algo sobre isso há muito tempo. Obrigado delnan, por encontrar o link. Faria sentido, já que sabemos que os fabricantes de chips gostam de adicionar suas próprias instruções além do padrão x86-x64; portanto, se a máquina pode tirar vantagem, por que não?
DXM 23/09