Por que algumas linguagens de programação são mais rápidas ou mais lentas que outras?


82

Percebi que alguns aplicativos ou algoritmos criados em uma linguagem de programação, como C ++ / Rust, são executados mais rápido ou mais rápido do que os criados em Java / Node.js, executando na mesma máquina. Eu tenho algumas perguntas sobre isso:

  1. Por que isso acontece?
  2. O que governa a "velocidade" de uma linguagem de programação?
  3. Isso tem algo a ver com gerenciamento de memória?

Eu realmente aprecio se alguém quebrar isso para mim.


18
Observe que, para a JVM e o CLR, em particular, uma pesquisa extensa foi feita para otimizar as VMs e elas podem superar o C ++ compilado em muitas circunstâncias - mas é fácil fazer um benchmarking ingênuo errado.
chrylis -on strike-


26
Dito isto, agrupar Java e qualquer coisa relacionada a Javascript é um insulto.
Raphael

5
Estou dividido entre fechar isso como muito amplo (os livros podem ser escritos sobre os tópicos relevantes!) Ou duplicados . Votos da comunidade, por favor!
Raphael

4
esta questão também é bastante semelhante o que determina a velocidade de uma linguagem de programação
vzn

Respostas:


96

No design e implementação da linguagem de programação, há um grande número de opções que podem afetar o desempenho. Vou mencionar apenas alguns.

Em última análise, todos os idiomas precisam ser executados executando o código da máquina. Uma linguagem "compilada" como C ++ é analisada, decodificada e traduzida em código de máquina apenas uma vez, em tempo de compilação. Uma linguagem "interpretada", se implementada de maneira direta, é decodificada no tempo de execução, a cada passo, a cada momento. Ou seja, toda vez que executamos uma declaração, o intérprete deve verificar se é um if-then-else, ou uma tarefa, etc. e agir em conformidade. Isso significa que, se fizermos um loop de 100 vezes, decodificamos o mesmo código 100 vezes, perdendo tempo. Felizmente, os intérpretes geralmente otimizam isso através, por exemplo, de um sistema de compilação just-in-time. (Mais corretamente, não existe linguagem "compilada" ou "interpretada" - é uma propriedade da implementação, não da linguagem. Ainda assim,

Diferentes compiladores / intérpretes realizam diferentes otimizações.

Se o idioma tiver gerenciamento automático de memória, sua implementação precisará executar a coleta de lixo. Isso tem um custo de tempo de execução, mas alivia o programador de uma tarefa suscetível a erros.

Uma linguagem pode estar mais próxima da máquina, permitindo ao programador especialista otimizar tudo e extrair mais desempenho da CPU. No entanto, é discutível se isso é realmente benéfico na prática, uma vez que a maioria dos programadores não otimiza realmente a micro-otimização e, muitas vezes, uma boa linguagem de nível superior pode ser otimizada pelo compilador melhor do que o programador médio faria. (No entanto, às vezes, estar mais distante da máquina também pode ter seus benefícios! Por exemplo, Haskell é de nível extremamente alto, mas, graças ao seu design, as opções podem apresentar linhas verdes muito leves.)

A verificação de tipo estático também pode ajudar na otimização. Em uma linguagem interpretada e de tipo dinâmico, toda vez que alguém calcula x - y, o intérprete geralmente precisa verificar se ambos x,ysão números e (por exemplo) gerar uma exceção caso contrário. Essa verificação pode ser ignorada se os tipos já tiverem sido verificados no momento da compilação.

Alguns idiomas sempre relatam erros de tempo de execução de maneira sã. Se você escreve a[100]em Java, onde apossui apenas 20 elementos, obtém uma exceção de tempo de execução. Em C, isso causaria um comportamento indefinido, o que significa que o programa pode travar, substituir alguns dados aleatórios na memória ou até executar absolutamente qualquer outra coisa (o padrão ISO C não impõe limites). Isso requer uma verificação de tempo de execução, mas fornece uma semântica muito melhor para o programador.

No entanto, lembre-se de que, ao avaliar um idioma, o desempenho não é tudo. Não fique obcecado com isso. É uma armadilha comum tentar otimizar tudo e ainda assim não conseguir identificar que uma estrutura ineficiente de algoritmos / dados está sendo usada. Knuth disse uma vez que "a otimização prematura é a raiz de todo mal".

Não subestime o quão difícil é escrever um programa corretamente . Freqüentemente, pode ser melhor escolher uma linguagem "mais lenta" que tenha uma semântica mais amigável ao ser humano. Além disso, se houver algumas partes críticas de desempenho específicas, elas sempre poderão ser implementadas em outro idioma. Como referência, no concurso de programação do ICFP de 2016 , estas foram as línguas usadas pelos vencedores:

1   700327  Unagi                       Java,C++,C#,PHP,Haskell
2   268752  天羽々斬                     C++, Ruby, Python, Haskell, Java, JavaScript
3   243456  Cult of the Bound Variable  C++, Standard ML, Python

Nenhum deles usava um único idioma.


81
Uma versão de toda a citação de Knuth : "Os programadores perdem muito tempo pensando ou se preocupando com a velocidade de partes não críticas de seus programas, e essas tentativas de eficiência têm um forte impacto negativo quando a depuração e a manutenção são consideradas. Devemos esquecer pequenas eficiências, digamos, 97% das vezes: a otimização prematura é a raiz de todo mal. No entanto, não devemos desperdiçar nossas oportunidades nesses 3% críticos. "
Derek Elkins

6
Além disso, algumas línguas garantir coisas aparentemente inocentes que podem afetar a capacidade do compilador para otimizar, consulte estrita aliasing em C ++ vs. Fortran
PlasmaHH

9
Juntou-se para que eu pudesse aprovar o comentário por @DerekElkins. Freqüentemente, o contexto dessa citação está ausente, algumas vezes levando à conclusão de que defende que toda otimização é má.
pipe

9
@DerekElkins Ironicamente, você perdeu a parte mais importante: as duas frases imediatamente a seguir. "Um bom programador não será levado à complacência por esse raciocínio; será prudente examinar atentamente o código crítico; mas somente após a identificação desse código. Geralmente, é um erro fazer julgamentos a priori sobre quais partes de um são realmente críticos, pois a experiência universal dos programadores que usam ferramentas de medição é que suas suposições intuitivas falham. " PDF p268
8bittree

9
@DerekElkins Para ser claro, não quero colocar palavras na sua boca dizendo que você estava reivindicando isso, mas muitas vezes me deparo com pessoas adicionando um pouco à citação básica e pensando que Knuth estava defendendo a otimização prematura 3 Na maioria das vezes, quando o artigo completo deixa claro que ele sempre se opõe à otimização prematura, quase sempre se opõe a pequenas otimizações, mas defende pequenas otimizações em seções medidas como críticas.
8bittree

19

O que governa a "velocidade" de uma linguagem de programação?

Não existe a "velocidade" de uma linguagem de programação. Existe apenas a velocidade de um programa específico escrito por um programador específico executado por uma versão específica de uma implementação específica de um mecanismo de execução específico executando em um ambiente específico.

Pode haver grandes diferenças de desempenho na execução do mesmo código escrito no mesmo idioma na mesma máquina usando implementações diferentes. Ou mesmo usando versões diferentes da mesma implementação. Por exemplo, executar exatamente o mesmo benchmark ECMAScript na mesma máquina, usando uma versão do SpiderMonkey de 10 anos atrás versus uma versão deste ano provavelmente trará um aumento de desempenho entre 2 × –5 ×, talvez até 10 ×. Isso significa que o ECMAScript é 2x mais rápido que o ECMAScript, porque executar o mesmo programa na mesma máquina é 2x mais rápido com a implementação mais recente? Isso não faz sentido.

Isso tem algo a ver com gerenciamento de memória?

Na verdade não.

Por que isso acontece?

Recursos. Dinheiro. A Microsoft provavelmente emprega mais pessoas fazendo café para seus programadores de compiladores do que a comunidade inteira de PHP, Ruby e Python combinada e pessoas trabalhando em suas VMs.

Para mais ou menos qualquer recurso de uma linguagem de programação que afeta o desempenho de alguma forma, também há uma solução. Por exemplo, C (eu estou usando C aqui como substituto de uma classe de linguagens semelhantes, algumas das quais existiam antes de C) não é seguro para a memória, de modo que vários programas C em execução ao mesmo tempo podem atropelar memória um do outro. Então, inventamos a memória virtual e fazemos com que todos os programas C passem por uma camada de indireção, para que possam fingir que são os únicos em execução na máquina. No entanto, isso é lento e, portanto, inventamos a MMU e implementamos a memória virtual no hardware para acelerá-la.

Mas! Idiomas seguros para memória não precisam de tudo isso! Ter memória virtual não os ajuda nem um pouco. Na verdade, é pior: não apenas a memória virtual não ajuda as linguagens seguras, mas também a memória virtual, mesmo quando implementada em hardware, afeta o desempenho. Isso pode ser especialmente prejudicial ao desempenho dos coletores de lixo (que é o que um número significativo de implementações de linguagens seguras para memória).

Outro exemplo: as CPUs modernas de uso geral convencionais empregam truques sofisticados para reduzir a frequência de falhas de cache. Muitos desses truques significam tentar prever qual código será executado e que memória será necessária no futuro. No entanto, para idiomas com um alto grau de polimorfismo de tempo de execução (por exemplo, idiomas OO), é realmente difícil prever esses padrões de acesso.

Porém, existe outra maneira: o custo total de falhas de cache é o número de falhas de cache multiplicado pelo custo de uma falha individual de cache. As CPUs convencionais tentam reduzir o número de erros, mas e se você pudesse reduzir o custo de um erro individual?

A CPU Azul Vega-3 foi projetada especificamente para executar JVMs virtualizadas e tinha uma MMU muito poderosa com algumas instruções especializadas para ajudar na coleta de lixo e na detecção de escape (o equivalente dinâmico à análise de escape estático) e poderosos controladores de memória e todo o sistema ainda pode progredir com mais de 20.000 falhas de cache pendentes em voo. Infelizmente, como a maioria das CPUs específicas de idioma, seu design foi simplesmente gasto e forçado pelos "gigantes" Intel, AMD, IBM e similares.

A arquitetura da CPU é apenas um exemplo que afeta a facilidade ou a dificuldade de implementar uma linguagem de alto desempenho. Uma linguagem como C, C ++, D, Rust, que seja adequada ao modelo de programação de CPU mainstream moderno, será mais fácil de acelerar do que uma linguagem que precisa "combater" e contornar a CPU, como Java, ECMAScript, Python, Ruby , PHP.

Realmente, é tudo uma questão de dinheiro. Se você gastar quantias iguais de dinheiro para desenvolver um algoritmo de alto desempenho no ECMAScript, uma implementação de alto desempenho do ECMAScript, um sistema operacional de alto desempenho projetado para o ECMAScript, uma CPU de alto desempenho projetada para o ECMAScript como foi gasto nos últimos décadas para fazer com que os idiomas do tipo C sejam mais rápidos, é provável que você tenha desempenho igual. Só que, neste momento, muito mais dinheiro foi gasto para tornar as linguagens do tipo C mais rápidas do que para as linguagens do ECMAScript, e as suposições das linguagens do tipo C são agrupadas em toda a pilha, de MMUs e CPUs a sistemas operacionais e sistemas operacionais. sistemas de memória virtual até bibliotecas e estruturas.

Pessoalmente, eu estou mais familiarizado com Ruby (que geralmente é considerado uma "linguagem lenta"), então darei dois exemplos: a Hashclasse (uma das estruturas de dados centrais em Ruby, um dicionário de valores-chave) no Rubinius A implementação do Ruby é escrita em Ruby 100% puro e tem o mesmo desempenho que oHashclasse em YARV (a implementação mais usada), escrita em C. E há uma biblioteca de manipulação de imagens escrita como uma extensão C para YARV, que também possui uma "versão de fallback" pura (lenta) do Ruby para implementações que não suporta C, que usa uma tonelada de truques Ruby altamente dinâmicos e reflexivos; um ramo experimental do JRuby, utilizando a estrutura de intérpretes Truffle AST e a estrutura de compilação Graal JIT do Oracle Labs, pode executar a "versão de fallback" pura do Ruby tão rápido quanto o YARV pode executar a versão C altamente otimizada original. Isso é simplesmente (bem, qualquer coisa, menos) alcançado por algumas pessoas realmente inteligentes fazendo coisas realmente inteligentes com otimizações dinâmicas de tempo de execução, compilação JIT e avaliação parcial.


4
Embora tecnicamente as linguagens não sejam inerentemente rápidas, algumas linguagens têm um foco maior em permitir que o programador crie código rápido. C é otimizado principalmente para CPUs e não o contrário. Por exemplo, C escolheu tamanhos fixos ints por razões de desempenho, apesar de números inteiros ilimitados, como os usados ​​pelo Python, serem muito mais matematicamente naturais. A implementação de números inteiros ilimitados no hardware não seria tão rápida quanto os números inteiros de tamanho fixo. Os idiomas que tentam ocultar os detalhes da implementação precisam de otimizações complexas para se aproximarem das implementações ingênuas de C.
gmatht

1
C tem um histórico - foi criado para tornar um sistema escrito em linguagem assembly portátil para outros sistemas. Portanto, o objetivo original era fornecer um "montador portátil" para o Unix, e foi muito bem projetado. Ele se saiu tão bem desde 1980-1995-ish que tinha massa crítica quando o Windows 95 foi lançado.
Thorbjørn Ravn Andersen 26/03

1
Eu discordo do comentário sobre recursos. Não é o número de pessoas da equipe que importa, é o nível de habilidade das melhores pessoas da equipe.
Michael Kay

"A Microsoft provavelmente emprega mais pessoas que preparam café para seus programadores de compiladores do que toda a comunidade PHP, Ruby e Python combinada tem pessoas trabalhando em suas VMs". Suponho que isso depende de até que ponto você deseja estender o termo "programador de compiladores" quanto você inclui com isso (a Microsoft desenvolve muitos compiladores). Por exemplo, apenas a equipe do compilador VS C ++ é um AFAIK relativamente pequeno.
Cubic

7

Teoricamente, se você escrever um código que faça exatamente o mesmo em duas linguagens e compilar os dois usando um compilador "perfeito", o desempenho de ambos deverá ser o mesmo.

Na prática, há várias razões pelas quais o desempenho será diferente:

  1. Alguns idiomas são mais difíceis de otimizar.

    Isso inclui especialmente recursos que tornam o código mais dinâmico (digitação dinâmica, métodos virtuais, ponteiros de função), mas também, por exemplo, coleta de lixo.

    Existem várias maneiras de tornar o código rápido usando esses recursos, mas geralmente ele acaba pelo menos um pouco mais lento do que sem usá-los.

  2. Algumas implementações de linguagem precisam fazer alguma compilação em tempo de execução.

    Isso se aplica especialmente a idiomas com máquinas virtuais (como Java) e idiomas que executam o código-fonte, sem etapa intermediária para binário (como JavaScript).

    Essas implementações de linguagem precisam trabalhar mais em tempo de execução, o que afeta o desempenho, especialmente o tempo de inicialização / desempenho logo após a inicialização.

  3. As implementações de idioma intencionalmente gastam menos tempo em otimizações do que poderiam.

    Todos os compiladores se preocupam com o desempenho do próprio compilador, não apenas com o código gerado. Isso é especialmente importante para os compiladores de tempo de execução (compiladores JIT), pois levar muito tempo para compilar diminui a execução do aplicativo. Mas isso se aplica aos compiladores antecipados, como os do C ++ também. Por exemplo, a alocação de registros é um problema completo do NP, portanto, não é realista resolvê-lo perfeitamente e, em vez disso, são utilizadas as heurísticas executadas em tempo razoável.

  4. Diferenças de idiomas em diferentes idiomas.

    O código escrito no estilo comum para um determinado idioma (código idiomático) usando bibliotecas comuns pode resultar em diferenças no desempenho, porque esse código idiomático se comporta sutilmente de maneira diferente em cada idioma.

    Como exemplo, considere vector[i]em C ++, list[i]em C # e list.get(i)em Java. O código C ++ provavelmente não faz verificação de intervalo e não realiza chamadas virtuais, o código C # executa a verificação de intervalo, mas nenhuma chamada virtual e o código Java executa a verificação de intervalo e é uma chamada virtual. Todos os três idiomas suportam métodos virtuais e não virtuais e o C ++ e o C # podem incluir verificação de intervalo ou evitá-lo ao acessar a matriz subjacente. Mas as bibliotecas padrão dessas linguagens decidiram escrever essas funções equivalentes de maneira diferente e, como conseqüência, seu desempenho será diferente.

  5. Alguns compiladores podem estar perdendo algumas otimizações.

    Os escritores do compilador têm recursos finitos, portanto, eles não podem implementar todas as otimizações possíveis, mesmo ignorando os outros problemas. E os recursos que eles têm podem se concentrar mais em uma área de otimização do que em outras. Como conseqüência, o código escrito em idiomas diferentes pode ter um desempenho diferente devido a diferenças em seus compiladores, mesmo que não exista uma razão fundamental para que um idioma seja mais rápido ou até mais fácil de otimizar que o outro.


Alguma linguagem não tem um compilador. Para alguns idiomas, não pode haver um compilador ( referência ).
Raphael

3
Para alguns idiomas, não pode haver um compilador estático . A compilação dinâmica não é afetada pela indecidibilidade das propriedades estáticas.
Jörg W Mittag 24/03

Se os idiomas são diferentes o suficiente, eles não têm "código que faz exatamente o mesmo". Eles podem ter código que produz a mesma saída ou comportamento observável pelo usuário, que não é a mesma coisa. Então, eu discordo de sua premissa.
einpoklum - reinstala Monica

@einpoklum Não vejo a distinção. Com algumas exceções (como a sincronização de encadeamento), que eu acho que não são interessantes aqui, as especificações de linguagem geralmente permitem otimizações que preservam o comportamento observável. Que tipo de comportamento você tem em mente que não é observável pelo usuário, mas não pode ser otimizado?
svick

Teoricamente, qualquer linguagem interpretada pode ser “compilada” gerando um arquivo EXE que consiste em um intérprete + no código-fonte do programa.
dan04

1

Essa é uma pergunta muito geral, mas no seu caso a resposta pode ser simples. O C ++ compila no código da máquina, onde o Java compila no código de byte Java, que é executado em uma máquina virtual Java (embora também exista uma compilação just-in-time, que compila ainda mais o código de byte Java no código da máquina nativa). Outra diferença pode ser a coleta de lixo, que é um serviço que apenas o Java fornece.


2
Essa é uma resposta simplista demais. Existem configurações nas quais o Java é mais rápido.
Raphael

4
Também existem implementações de Java que compilam para código de máquina e implementações interpretadas de C ++. E o que é "código de máquina" de qualquer maneira, se eu tenho uma CPU picoJava que executa nativamente o bytecode da JVM e o interpretador JPC x86 está sendo executado na JVM, o que faz com que o código do objeto x86 seja "código da máquina" e o bytecode da JVM não?
Jörg W Mittag 24/03

2
Nitpick: Não apenas o Java fornece coleta de lixo ... e, mesmo que você considere apenas C ++ e Java, alguns programas de estruturas / bibliotecas do C ++ possuem instalações de coleta de lixo.
einpoklum - reinstala Monica

Compilar com código de máquina nativo geralmente melhora o desempenho. No entanto, em alguns casos limitados, um intérprete de alta qualidade pode superar um ingênuo compilador just-in-time.
DepressedDaniel

@ JörgWMittag O truque é compilar com o código de máquina nativo - o código de máquina que o processador host entende - e então pular diretamente para o código chamado, para que possa ser executado sem interpretação. Será x86 em um chip x86 e bytecodes da JVM em uma CPU picoJava.
DepressedDaniel

-5

Sua pergunta é muito geral, por isso tenho medo de não dar uma resposta exata de que você precisa.

Para minha melhor explicação, vejamos a plataforma C ++ e .Net.

C ++, muito próximo ao código da máquina e um dos programas preferidos nos tempos antigos (há mais de 10 anos?) Por causa do desempenho. Não há muitos recursos necessários para desenvolver e executar o programa C ++, mesmo com o IDE, eles são considerados muito leves e muito rápidos. Você também pode escrever código C ++ no console e desenvolver um jogo a partir daí. Em termos de memória e recursos, esqueci aproximadamente a capacidade necessária em um computador, mas a capacidade é algo que você não pode comparar com a geração atual de linguagem de programação.

Agora vamos dar uma olhada em .Net. O pré-requisito para o desenvolvimento de .Net é um IDE gigante que consiste em não apenas um tipo de linguagem de programação. Mesmo que você queira apenas desenvolver, digamos C #, o próprio IDE incluirá muitas plataformas de programação por padrão, como J #, VB, dispositivos móveis e etc por padrão. A menos que você faça a instalação personalizada e instale apenas exatamente o que deseja, desde que tenha experiência suficiente para jogar com a instalação do IDE.

Além de instalar o próprio software IDE, o .Net também possui uma enorme capacidade de bibliotecas e estruturas com o objetivo de facilitar o acesso a qualquer tipo de plataforma de que os desenvolvedores precisam E não precisam.

Desenvolver o .Net pode ser uma experiência divertida, porque muitas funções e componentes comuns estão disponíveis por padrão. Você pode arrastar e soltar e usar muitos métodos de validação, leitura de arquivos, acesso ao banco de dados e muito mais no IDE.

Como resultado, é uma troca entre recursos de computador e velocidade de desenvolvimento. Essas bibliotecas e estruturas ocupam memória e recursos. Quando você executa um programa no .Net IDE, ele pode consumir muito tempo tentando compilar as bibliotecas, componentes e todos os seus arquivos. E quando você faz a depuração, seu computador exige muitos recursos para gerenciar o processo de depuração no seu IDE.

Geralmente, para desenvolver o .Net, você precisa de um bom computador com alguns RAM e processador. Caso contrário, você também pode não programar. Nesse aspecto, a plataforma C ++ é muito melhor que .Net. Embora você ainda precise de um bom computador, a capacidade não será muito preocupante em comparação com o .Net.

Espero que minha resposta possa ajudar com sua pergunta. Deixe-me saber caso você queira saber mais.

EDITAR:

Apenas um esclarecimento ao meu ponto principal, respondo principalmente à pergunta "O que governa a velocidade da programação".

Do ponto de vista do IDE, o uso da linguagem C ++ ou .Net no IDE relativo não afeta a velocidade de escrita do código, mas afetará a velocidade do desenvolvimento, porque o compilador do Visual Studio leva mais tempo para executar o programa, mas o C ++ IDE é muito mais leve e consome menos recursos do computador. Portanto, a longo prazo, você pode programar mais rapidamente com o tipo de IDE C ++, comparado com o .Net IDE, o que depende muito das bibliotecas e da estrutura. Se você demorar o tempo de espera para o IDE iniciar, compilar, executar o programa e etc., isso afetará a velocidade da programação. A menos que "a velocidade da programação" seja realmente focada apenas na "velocidade de escrever código".

A quantidade de bibliotecas e estrutura no Visual Studio também consome a capacidade do computador. Não tenho certeza se isso responde à questão do "gerenciamento de memória", mas quero apenas salientar que o Visual Studio IDE pode consumir muitos recursos ao executá-lo e, assim, diminuir a "velocidade de programação" geral. Obviamente, isso não tem nada a ver com "velocidade de escrever código".

Como você deve ter adivinhado, não conheço muito C ++, pois apenas o uso como exemplo; meu ponto principal é o tipo de IDE pesado do Visual Studio que consome recursos do computador.

Se eu entendi a idéia e não respondi à pergunta inicial do tópico, peça desculpas pelo longo post. Mas eu aconselho o iniciador de tópicos a esclarecer a questão e pergunte exatamente o que ele precisa saber sobre "mais rápido" e "mais lento"


6
Apenas para constar, o desenvolvimento do .NET requer apenas o .NET SDK (e, para execução, o próprio .NET runtime). Você pode usar um editor de texto sem formatação e chamar o compilador na linha de comando. O IDE (suponho que você esteja se referindo ao Visual Studio) NÃO é necessário, embora certamente ajude em qualquer projeto considerável (Intellisense, depurador, etc etc). Também existem IDEs mais leves, como o SharpDevelop, com menos sinos e assobios.
MetalMikester 24/03

16
Você certamente pode desenvolver no .Net sem um IDE. Mas não vejo como o IDE é relevante para a velocidade do código escrito em um idioma.
svick

8
@MetalMikester: E, claro, o Visual Studio é o IDE ideal para o desenvolvimento de C ++ no Windows.
Jörg W Mittag 24/03

3
E compilar C ++ em código .Net é apenas uma opção de compilador; o suposto abismo são pontes com um clique do mouse no visual studio.
MSalters 24/03

1
Não tenho certeza se chamaria o C ++ moderno de "muito próximo ao código da máquina". C original, sim; foi concebido como um montador portátil e permaneceu muito próximo disso (embora a biblioteca padrão tenha crescido e vários compiladores ofereçam complementos à linguagem apropriada que o leva mais longe de suas origens). C ++ original (C com classes), talvez; reescrever uma variante de C que inclua classes em C puro não é tão difícil, quando a discussão anterior se aplica. Mas C ++ moderno, com modelos, polimorfismo e tudo o mais sob o sol? Isso dificilmente "está muito próximo do código da máquina".
a CVn 27/03
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.