C ++ vs C #



Todo mundo sabe que não há nada mais estúpido do que argumentar "qual idioma é melhor". Por exemplo, melhor para quê? Idiomas diferentes são bem-sucedidos em nichos diferentes - e é inútil tirar conclusões definitivas sem considerar isso.

Mas o que acontece se você recorrer a especialistas experientes que compreendem tudo isso e pedir que organizem o C ++ vs C # holivar? Acontece que você pode descobrir muitos detalhes interessantes. A palavra "plataforma cruzada" pode ser aplicada de ambas as formas nos dois idiomas, mas o que isso significa na prática? O C ++ está se desenvolvendo ativamente agora? C # já quebrou a compatibilidade com versões anteriores? As respostas podem ser óbvias para aqueles que já estão profundamente imersos nos dois idiomas ao mesmo tempo, mas existem poucas pessoas - e todo mundo aprenderá algo novo.

De C ++, Sergey sermp Platonov , Presidente do Comitê de Programa da Conferência C ++ na Rússia , participou. O lado do C # foi representado por Anatoly Kulakov - ele está incluído no PC da conferência DotNext e entre os líderes do DotNetRu . E o líder da discussão, na vida em que esses dois mundos coexistem, era Dmitry mezastel Nesteruk .




Dmitry: Boa tarde, colegas. Bem-vindo a reuniões informais sobre o tema das linguagens de programação. Na Internet, somos constantemente lembrados de que idiomas não podem ser comparados. E hoje faremos exatamente o que você não pode fazer: compare C ++ com C # e .NET, seus prós e contras. Apresente-se, por favor.

Anatoly: Meu nome é Anatoly, e hoje vou me afogar em C #, porque tenho estudado esse idioma desde suas primeiras versões e, ao que parece, sei tudo sobre ele.

Sergey: Olá, meu nome é Sergey, hoje vou me afogar em C ++. Dima disse corretamente que compararemos os prós e os contras. Todo mundo chama de "profissionais", sabe-se que, na verdade, o C # nesta discussão será um sinal de menos. Está certo, Anatoly?

Anatoly: C # tem mais duas vantagens! Portanto, acho que esse é um desenvolvimento evolutivo das vantagens que já são obsoletas e não são capazes de competir em praticamente qualquer lugar.



Educação


Dmitry: Eu tenho o primeiro tópico para a nossa discussão. Imagine que os novos estudantes venham para a universidade, eles precisam do primeiro idioma. Qual você acha que deveria ser o primeiro idioma que as pessoas aprendem no primeiro ano: C ++, C # ou assembler em geral?

Sergey: Eu ensinei por algum tempo, então tenho uma opinião estabelecida. Entendo que aqui vamos discutir qual linguagem é melhor e defendo C ++ ... Mas, para aprender C ++, você precisa entender a arquitetura do computador. E com isso, o grande problema de ensinar os alunos (pelo menos na universidade onde lecionei). E para ensinar algoritmos e outras coisas, você provavelmente precisará de algo que não se concentre na infraestrutura, na própria linguagem. Aqui, Eiffel foi uma tentativa de fazer isso, mas também há muita mágica. Portanto, eu diria que nenhum dos nossos dois idiomas é adequado.

A programação é diferente, e não é a “programação” que ensina, mas algoritmos, estruturas de dados e assim por diante. É possível que faça sentido escolher seu próprio instrumento em cada assunto. Entenda algum tipo de estrutura de dados Lisp. E o C ++, portanto, deve ser dado depois que os alunos entenderem algo sobre arquitetura. E então será possível entender por que toda essa dor e sofrimento. Eu nem vou argumentar que as vantagens são sobre dor.

Anatoly: Sim, concordo plenamente que você precisa separar objetos e não colocá-lo em "programação" e martelar tudo em um idioma. Mas se você chegar ao ponto em que aprendeu o básico, os fundamentos, os algoritmos e começar a escolher algum tipo de linguagem industrial, é claro que o C # será muito melhor. Porque isso não força você a aprender tudo isso no nível de arquiteturas, bytes de memória e outros "pôr do sol à mão". Ele fornece uma linguagem imediatamente compreensível, sintaxe simples e, nesse idioma, do primeiro ou do segundo ano, você pode ganhar dinheiro bastante tangível.

Dmitry: Há um argumento de que não dar aos alunos iniciantes algumas coisas como ponteiros é algum tipo de sacrilégio. Eles terão um enorme buraco se uma pessoa não entender que, por exemplo, um link é realmente apenas o endereço de uma variável na memória. O que você acha disso?

Anatoly: 20 anos atrás, isso era verdade quando os computadores não tinham memória suficiente, discos insuficientes e outras coisas. Agora, observe esses javascripts, eles arrastam 500 megabytes de bibliotecas para cada "olá mundo". Quanto eles levam na memória? Qual é o desempenho deles? Quais são os links aí? Sim, ninguém liga. O principal é rolar e liberar rapidamente algo na produção. Não afirmo que seja um caminho bom ou correto, afirmo que é necessário mudar junto com as realidades. Talvez agora não seja tão importante quanto o seu link leva.

Sergey: Provavelmente dependendo de onde. Dmitry, pelo que entendi, estava interessado em negociação algorítmica - posso imaginar vividamente como ele puxa bibliotecas em JS para enviar um pedido à central.

Dmitry: Bem, sim, é claro, na prática ninguém usa idiomas desse tipo lá. Embora teoricamente isso seja possível: não vamos esquecer que dinheiro fraco não está sendo jogado na infraestrutura do JS. Mecanismos que transformam a compilação JS em tudo e qualquer coisa. Muitos consideram esse idioma como o idioma de primeira classe para tudo em geral.

Naturalmente, a negociação de algo é agora uma disciplina remota de tal disciplina, mas a negociação de algo e a matemática financeira como um todo geralmente são uma área específica. Apenas predomina C ++. E predomina em parte devido à inércia, simplesmente por razões históricas: no começo todos estavam em C ++, e essa área é conservadora.

Sergey: Eu não concordo. Agora trabalho na fintech, e colegas que estão aqui desde o início do comércio algorítmico falam sobre grandes empresas que escreveram pela primeira vez em Java. No início, o Java lidou com a negociação algorítmica, mas quando o mercado começou a crescer e os concorrentes com C ++ apareceram, em algum momento eles simplesmente não conseguiram, não conseguiram fazer tudo com eficiência ... Portanto, nem todos na negociação algorítmica começaram com C ++. Apenas aqueles que não escreveram morreram. Uma seleção tão natural.

Dmitry: Na verdade, você pode ampliá-lo. Existem muitos exemplos em que bancos grandes mantêm seus algoritmos em um documento do Excel. Eles também usam o Excel como servidor para calcular tudo isso. Existem freios infernais, mas tudo depende se você está negociando em alta frequência (ou geralmente em alta frequência). Se você é um formador de mercado, é natural que você precise de alto desempenho, e aí o negócio não se limita nem ao C ++, então vamos para as linguagens de hardware e HDL.

Mas nossa discussão não é apenas sobre negociação algorítmica, mas também sobre coisas simples. Aqui eu dou um exemplo. Em conexão com a construção, eu precisava escrever várias pequenas aplicações calculando coisas diferentes: por exemplo, como colocar tijolos ao redor do contorno de uma casa. E mal consigo imaginar como fazer essas coisas em C ++, porque tudo relacionado à interface do usuário é mais fraco lá. Existe apenas uma estrutura, Qt, e até escrever sobre ela é muito difícil. E se eu me sentar em C #, em WinForms, então simplesmente instalei o aplicativo.

Anatoly: Bem, a parte visual sempre foi uma força do C #. A Microsoft investiu muito em moldes, e mesmo em moldes de plataforma cruzada, e em geral na visualização. Portanto, se estamos falando de aplicativos visuais para a área de trabalho, parece-me que as vantagens geralmente estão muito, muito atrás.

Sergey: Bem, depende, como sempre. Eu realmente não gosto de interface do usuário, mas nos trunfos eu sempre tenho que fazer isso. Parece trazer JS e apenas interagir com os profissionais. Mas eu trabalhei com incorporado, e aí é difícil. As pessoas compraram algum tipo de mecanismo rápido e caro, mas ainda não conseguia lidar com a renderização normal da interface do usuário escrita em JS. E depois de reescrever tudo isso no Qt, acabou fazendo overclock. História comum.



Plataforma cruzada vs plataforma cruzada


Sergey: Eu queria esclarecer aqui. Eu não sei muito sobre C #, eu mesmo o toquei há muito tempo, nas primeiras versões (naquela época eu estava com uma compatibilidade com versões anteriores). Portanto, a pergunta é: ainda está sendo desenvolvido apenas pela Microsoft?

Anatoly: Não, agora é multiplataforma, aberta e verificada segundo a ISO (ECMA-334 e ISO / IEC 23270). A propósito, até onde eu sei, o C ++ ainda não possui uma especificação ISO aberta, apenas paga. E o C #, por outro lado, é completamente aberto. Desenvolvido por muitas empresas (incluindo Google, Amazon e Samsung), temos a .NET Foundation . Eu nem conheço um idioma mais aberto agora do que o C # e sua plataforma .NET.

Sergey: Bem, Haskell.

Anatoly: A propósito, o autor de Haskell trabalha na Microsoft Research e fez muitos esforços para fazer todo tipo de coisa interessante aparecer em C # - por exemplo, uma verificação estática, algum tipo de reflexão com a qual você provavelmente nem sonha.

Sergey: Eles podem sonhar, e até o trabalho está acontecendo nessa direção. Mas é claro que tudo tem seu próprio preço. Em C ++, eles simplesmente se recusam a pagar esse preço.

Anatoly: Qual? Eles são compilados por duas horas. Qual poderia ser o preço?

Sergey: Em C ++, o princípio da abstração de custo zero. Bem, isto é, uma máquina virtual não é uma abstração de custo zero, certo? Temos que aguentar isso.

Dmitry: Bem, mas uma máquina virtual pode, por exemplo, obscurecer o código para uma arquitetura específica. Enquanto em C ++, se eu usar a instrução AVX em um computador sem AVX, meu processo será encerrado. Eu diria que esse argumento não é inteiramente correto, porque teoricamente - enfatizo teoricamente - o JIT pode fazer o que C ++ não está disponível. Ou seja, otimização no momento do lançamento.

Sergey: Mas em C ++, durante a compilação, você pode controlar completamente as instruções necessárias. Nesse caso, você não o controla com as mãos, mas desiste do instrumento (compilador). Olha, quais instruções estão nessa arquitetura, que conjunto de instruções ...

Dmitry: Isso é compreensível. Mas você pode formulá-lo desta maneira: como existem milhões de plataformas, nunca teremos nenhum tipo de ideal, porque não podemos lançar um milhão de versões com diferentes sinalizadores de compilação. Certo? Normalmente, lançamos x86 e x64, mas não dividimos tudo em alguns subgrupos.

Sergey: Por que não podemos? Século XXI. Segure o Docker com parâmetros diferentes, isso é tudo.

Dmitry: Quando temos um cliente final que baixa nosso aplicativo, ele deseja baixar um binário específico. E neste binário, o melhor que podemos fazer é ficar em todos os lugares se. Como "se cpuid é assim e o suporte avx é assim, então usamos a versão 25 do algoritmo". Como resultado, precisamos de 25 versões diferentes do mesmo algoritmo, porque a aceleração depende das plataformas, depende da plataforma.

Sergey: Eu provavelmente concordo. Para ser sincero, nunca criei um produto não interno. Estou principalmente em empresas que usam seus produtos.

Dmitry: Bem, é claro, a melhor opção é quando você conhece previsivelmente a arquitetura. Nesse caso, a rigor, ninguém obriga a usar as instruções x86. Você pode pegar um cartão específico (por exemplo, Nvidia Tesla) e fazer o que quiser. Essa é a minha abordagem também, eu controlo minha arquitetura. Mas quando você toma decisões de mercado de massa para o usuário ... Se você usa algum ReSharper condicional, ele não pode simplesmente usar e usar a aceleração da GPU para quaisquer índices arbitrários. Porque a aceleração da GPU não é portátil.

Sergey: Na verdade, existem abordagens (agora você provavelmente não precisa entrar em detalhes), existem pessoas interessantes (o autor da abordagem, ao que parece, agora também mudou para a Microsoft). Aqui em nossa conferência, no ano anterior, havia um relatório sobre como escrever um programa desse tipo, que por si só entenderá o que é onde (relativamente fácil, novamente, abstrações de custo zero). Para que você possa escolher rapidamente e, se for o caso, reconstruir corretamente o código em um estilo CUDA ...

Dmitry: Na verdade, a própria CUDA está tentando resolver esse problema, porque na CUDA existe uma certa camada intermediária de PTX que lida com isso. Mas isso ainda é muito difícil, porque o ferro está mudando radicalmente evolutivamente e é muito difícil acompanhá-lo. E se observarmos o uso da aceleração de GPU, por exemplo, nos produtos da Adobe, eles usam uma seção muito restrita das tecnologias disponíveis. Se o seu cartão estiver correto - então sim, tudo estará correto. Mas se é um pouco exótico, nada é garantido a esse respeito.

Anatoly: Nesta discussão, abordamos um tópico bastante importante, como um mito: o C ++ foi declarado há muitos anos como uma linguagem de plataforma cruzada, mas, no momento, a plataforma cruzada é muito mais em C #. Um e apenas binário funciona em qualquer lugar onde o .NET é suportado, e isso está quase em todo lugar.

Sergey: Bem, isso também é bastante infundado. Como uma pessoa que passou a maior parte da minha vida incorporada, raramente vi o .NET ser suportado pela cadeia de ferramentas do fabricante de hardware. As empresas que produzem ferro usam o mesmo G ++ ou Clang ou o fazem começar a gerar código para sua plataforma.

Dmitry: Sim, mas o problema é que toda vez que fazem isso, eles perdem algo do C ++. Por exemplo, a Nokia usou uma variação do C ++, mas o seu C ++ estava com reviravoltas loucas e APIs loucas que enfureciam a todos. Ou seja, não é apenas C ++, mas C ++ para uma ou outra plataforma. E então os problemas começam. Por exemplo, tome o mesmo CUDA. É como se apenas deixasse os profissionais passarem por si; não é um compilador, mas apenas um driver. Mas, apesar disso, ela se preocupa com o fato de ainda usar algum tipo de estrutura para rasgar arquivos CUDA em partes de GPU e CPU. E às vezes ela não consegue.

Sergey: Eu não quis dizer isso nem um pouco. É que quando eu ouço ".NET roda em todos os lugares", a maior parte da minha biografia é revertida. Quando você compra um hardware com um processador personalizado, ele é fornecido com a entrega do G ++. E há C ++ comum, que o G ++ pode converter da cadeia de ferramentas em código de máquina suportado por esse processador em particular.

Dmitry: Mas, novamente, isso deve ser remontado ...

Sergey: Claro.

Dmitry: E a ideia de pegar um código positivo existente e arrastá-lo para um pedaço de ferro - essa idéia também não funciona, porque de repente você arrastou seu x86 comum para algum lugar, onde você tem 8 gigabytes de memória para tudo, e não é expandir: por exemplo, não há troca para disco, porque não há disco e acesso a ele. Isto é, se estamos falando de portabilidade. Depende dos objetivos, naturalmente.

Anatoly: os profissionais trabalham em mais dispositivos e, é claro, o incorporado é uma das partes mais fortes. Mas geralmente você precisa adaptar o seu código à plataforma. Isso é ruim. Eu posso cobrir um grande número de plataformas, arquiteturas, modelos com um código. Nos aspectos positivos, eu tive que pensar em cada plataforma individual: onde ela começará lá e em que condições. E é muito ruim, é muito contido.



Estabilidade, compatibilidade, desenvolvimento de linguagem


Dmitry: Abstrações de custo zero também foram mencionadas, mas o problema é que isso tem um preço enorme. Por exemplo, no .NET há um conceito de um tipo enumerado e uma interface IEnumerable. E para cada tipo, por exemplo, uma matriz, você pode pegar e passar por um iterador. Mas em C ++ não existe essa ideia. Devido à abstração de custo zero, para contornar a coleção, existem algumas begin () e end (), existem regras para seu trabalho, e tudo isso é muito mais complicado (especialmente para quem começa a programar). Este é um problema direto: como contornar uma matriz de A a Z.

Sergey: Se eu entendi direito do que você está falando ... Se você só precisa percorrer um contêiner do começo ao fim, agora basta escrever, como em algum Python.

Dmitry: Isso é tudo maravilhoso. Mas você, por exemplo, não usa polimorfismo para isso. Você não pode dizer que aqui eu tenho uma função que recebe um certo valor, que é enumerado a priori. Você não pode dizer que eu tenho um valor que implementa a interface, e essa interface possui um iterador, por exemplo.

Sergey: Estamos falando sobre qual C ++? Sobre C ++ em geral, C ++ do futuro, C ++, que agora estão sendo aceitos como padrão?

Dmitry: Bem, se nos profissionais do futuro será ...

Sergey: No C ++ 20, isso já está lá. Você já pode dizer, pode até se declarar. Essas não são interfaces, mas, como dizê-lo corretamente ... Em geral, você pode declarar que seu tipo deve satisfazer tais e tais condições. Por exemplo, ele tem início e fim, que retornam um iterador. E um iterador é um conceito tão preparado na biblioteca padrão. Ele diz o que é, descreve. Os iteradores também são diferentes. Em geral, tentamos, tornamos mais conveniente para as pessoas.

Dmitry: Parece-me que isso surgiu do fato de as pessoas perceberem que é difícil viver sem os conceitos de iterável de um objeto. Porque não está claro como escrever coisas generalizadas. Sim, a abstração de custo zero significa que não temos o custo de caminhar pela tabela em V ao pesquisar ... No .NET, existe apenas um método específico, por exemplo. E nós, para encontrá-lo, naturalmente, temos que gastar esforços, que as vantagens recusam. Mas, do ponto de vista da usabilidade, o resultado final não é tão bom, eu diria.

Sergey: Naturalmente, deve haver um equilíbrio. Você não pode ter tudo de uma vez.

Anatoly: Isso faz você se perguntar quantos anos se passaram. Línguas alternativas evoluem, e nelas essas coisas básicas aparecem desde o início. Agora eles estão alcançando algo mais substancial e interessante. E as vantagens ficam por dez anos com a mesma sintaxe incompreensível, abstrações obscuras, muletas incompreensíveis e subdesenvolvidas. Você pode colocar isso como um dos menos.

Sergey: Bem, vamos lá! O que significa "mal desenvolvido"?

Você mencionou um comitê - o C ++ também possui um comitê ISO que o desenvolve. Existem representantes lá, incluindo a Microsoft, que se afogam fortemente pelo fato de que "você não pode fazer isso porque temos muito legado que precisamos apoiar". Apenas C ++ é a linguagem já realizada. E, claro, ele caminha com muito cuidado. Uma das principais tarefas (que já foi declarada pela Straustrup ao criar) é a compatibilidade com C. Mas agora C já evoluiu bastante, é necessário designar com qual C é compatível.

E, na minha opinião, agora o C ++ está se desenvolvendo em um ritmo tremendo. Com relação aos conceitos e assim por diante - de fato, tudo cresce, é claro, não pela iterabilidade. De fato, o desenvolvimento segue o que Alexander Stepanov também descreveu - um dos autores do que agora chamamos de “programação generalizada”, a pessoa que realmente arrastou modelos, genéricos e assim por diante para o C ++. Para ser sincero, não sei o quanto o comitê é inspirado por essas idéias, mas parece-me que há definitivamente alguma interseção com elas.

Anatoly: Parece que todas essas metaclasses, iteradores são realmente inspiração, o que já era muitas décadas atrás. Mesmo se você usar metaprogramação, modelos, macros - todas essas pessoas experimentaram, trabalharam há muito tempo e existem conceitos muito mais simples, óbvios e compreensíveis. Em outros idiomas, tudo isso é feito um milhão de vezes melhor e mais rápido, com segurança de tipo, verificação de tempo de compilação e assim por diante.

Sergey: Espere, você já está falando sobre algo que nem todo mundo está disposto a pagar. Não quero que meu programa verifique algo em tempo de compilação sem meu conhecimento. Você entende?

Anatoly: Eu acho que tudo isso com sinalizadores pode ser configurado. Você define o nível de otimização e ele verifica ou não. Isto não é um problema.

Sergey: Muitas vezes você precisa controlar tudo com as mãos. Saiba exatamente o que está acontecendo. Porque as ferramentas - bem, isso.

Dmitry: Não é nem sobre ferramentas. Aqui, o fato de linguagens como D e Rust dizerem dizer: bem, sim, existe uma coisa que, quando você acessa um elemento da matriz, pode verificá-lo, mas não pode verificá-lo. E eles apenas entregam ao usuário, ou seja, você pode dizer "mas vamos desativar as verificações de array", "mas vamos ativá-lo". Ou seja, algum tipo de controle a esse respeito.

Sergey: Não está claro quando você tem segurança e segurança, como em Rust, não vejo a diferença com C, por exemplo, neste caso.

Anatoly: A diferença é que você pode escrever com segurança e rápido. E em C você tem que escrever perigosamente. Bem, sim, talvez rápido. Às vezes, a estabilidade é mais importante que a velocidade.

Dmitry: Na verdade, se começarmos a cavar esse tópico com novas linguagens, em C ++ há coisas que geralmente são muito difíceis de transmitir às pessoas. Uma pergunta simples: qual é o tamanho int? Na maioria dos idiomas, você sabe a resposta para esta pergunta. Você diz: int é 32 bits. Mas você não conhece os profissionais. Você sabe o tamanho do seu computador em particular porque se lembra dele, mas, estritamente falando, você nem deseja usar os tipos básicos porque eles não são determinísticos. E essas coisas me enfurecem quando há um conjunto de abordagens herdadas, como o int será diferente em plataformas diferentes. E agora já entendemos que isso não pode ser feito. Por que não dar um passo além disso e de alguma forma resolver esse problema?

Sergey: Bem, isso está decidido. Existem DSTs , os tipos necessários com um comprimento fixo. Agora, o representante da Rússia no comitê está arrastando um int de comprimento variável (bem, novamente, com abstração de custo zero).

Anatoly: Lembro-me corretamente de que existe um tamanho não determinístico de um ponteiro para um método? Ou seja, sob diferentes compiladores e plataformas diferentes, os ponteiros são diferentes?

Sergey: Naturalmente, isso é arquitetura. Quando você está perto do hardware, como garantir o tamanho do ponteiro, se estiver em 8 bits e em 64 bits?

Anatoly: E como se pode fazer aritmética nos indicadores depois disso? Isso é loucura.

Sergey: Quero dizer? Bem, com cuidado.

Anatoly: Entendo. A abordagem é clara em todos os lugares, controlando cuidadosamente tudo com alças.

Sergey: Bem, sim. Novamente, nos padrões modernos de C ++, as abordagens são desenvolvidas ... Se falamos sobre a escolha, nas vantagens modernas, de fato, há uma escolha entre usar o coletor de lixo. Só que o GC é construído lá em balcões de referência.

Em geral, em suas palavras, sinto muito que meus colegas não atualizam seu conhecimento sobre vantagens modernas há muito tempo.

Agora, pessoas como Straustrup, que fazem parte do panteão dos deuses positivos, vêm com muitas chamadas para descobrir como ensinar C ++ moderno. O problema é o que as pessoas pensam nas categorias C ++ de 2003 e ensinam nas mesmas categorias. E em conexão com isso, existem novos projetos e abordagens interessantes, existem cursos modernos - digamos que os caras da Yandex fizeram um curso maravilhoso. E agora, em vantagens, é considerado uma má educação, por exemplo, usar puro novo e excluir.

Dmitry: Quanto ao seu comentário sobre a atualização do conhecimento ... A nuance é que minha abordagem, por exemplo, é usar o pequeno delta de C ++, que é garantido que funcionará para mim e com o qual sou "amigo". Você vê, C ++ é extenso. Há metaprogramação de modelos, e tudo ficaria bem, há muita mágica, mas, infelizmente, essa mágica é ilegível. Este é um código no qual um não-autor não pode descobrir isso sem nenhum conhecimento especial, em certo sentido uma caixa preta. E existem muitas dessas caixas negras nos profissionais, áreas de escuridão que não podem ser digeridas ... Eu gostaria, não sei, sua opção de ser calculada de forma previsível, bem e sem truques.

O exemplo mais simples é falar sobre intervalos ( intervalo-v3 e todo esse tópico). Por um lado, tudo isso é ótimo: há coisas que estão em C # há vários anos, permitindo, por exemplo, criar um calendário por quaisquer transformações da coleção padrão. Por outro lado, a maneira como é implementada em C ++ é simplesmente desagradável em comparação com C #: é pesada, não legível.

Sergey: Isso é saboroso. Eu, pelo contrário, gosto disso. Pelo que entendi, você está no relatório Nibler e em sua apresentação ...

Dmitry: Veja, quando o operador "ou" é usado para filtrar uma coleção, eu imediatamente tenho perguntas sobre isso. C # e Java fizeram tudo através do ponto, através dos métodos usuais.

Sergey: E me parece que isso é inspirado no Bash. Ou seja, é apenas um cano.

Dmitry: Bem, sim, provavelmente isso explica algo nessa abordagem.

Sergey: Isso explica muito! Vamos falar sobre o PowerShell, já que estamos falando sobre o Bash. Quem viu o PowerShell?

Anatoly: eu escrevo no PowerShell, um ótimo idioma. Mas, novamente, o tubo precisa ser inserido onde está, onde toda a arquitetura é permeada por ele. Não é onde você precisa executar uma única ação, e aqui está a sintaxe linguisticamente ruim.

Sergey: No tubo de alcance, é apenas muito ...

Dmitry: No intervalo, eles são usados, na minha opinião, pelo seguinte motivo ... Vou dizer o seguinte: se em C ++ havia métodos ou funções de extensão, você os usaria, é claro. Porque a coisa mais natural se você precisar classificar uma coleção é escrever "coleção. Filtro ()". E não "coleção | view :: filter () ".

Anatoly: Eu também tive a impressão de que você levou um tiro nas pernas por 20 anos, bateu no rosto, bateu com a cabeça na parede e, finalmente, disse: “Bem, agora fizemos tudo muito bem no 20º padrão, agora vamos ensinar os profissionais estão certos. " Sim, ninguém quer ensiná-los corretamente! Ou seja, é uma dor a longo prazo.

Sergey: Por favor, não ensine. Qual é o problema? Escreva em C # - negocie nele, escreva incorporado. Eu não me importo.

Anatoly: Bem, existem nichos estreitos onde os profissionais ainda estão lá.

Sergey: Incorporado é um "nicho estreito" ... Agora, olhando em volta da minha cozinha, vejo um monte de computadores.

Dmitry: Toda vez que viajo de avião, penso: "Droga, espero que essas vantagens tenham escrito tudo bem lá".

Sergey: Bem, a propósito, existe principalmente Ada, tanto quanto me lembro.

Dmitry: Ada domina lá, sim.

Anatoly: A propósito, recentemente deparei com um excelente artigo em que o autor em diferentes idiomas (cerca de 10) escreveu um driver de baixo nível - driver de rede para uma placa Intel de 10 gigabits. De C para Swift, JS, Python e, naturalmente, C #. Se olharmos para esses gráficos, que ele obteve, o C # em grandes lotes (quando os custos de lançamento são nivelados) fica em pé de igualdade com C e Rust.



Ou seja, se estamos falando sobre desempenho, pode ser um equívoco que o C # seja muito inferior em algum lugar. Há também um relatório descolado de Federico Luis Scratched Metal , onde ele mostrou como otimizou o código C # para os criadores de perfil de processador.

Sergey: Bem, começa de novo. O problema é que, quando você começa a otimizar esse Java, esse C #, fica claro por que não escrever em vantagens. Porque você precisa de conhecimentos específicos. E, como me parece, a vantagem de linguagens como C # e Java é nivelada - não um limiar de entrada muito alto. Até onde eu entendi, exatamente do que Dmitry estava falando: legibilidade do código, aprendendo muito, difícil de explicar alguns conceitos e assim por diante.

Anatoly: trabalho 99% do meu tempo escrevendo em C # "normal" - seguro, estável e funcionando o tempo todo. E 1% do tempo eu quero escrever algum tipo de código rápido e de baixo nível. E esse c # me permite também. Mas minha ferramenta principal ainda é estável, legível, sem erros ...

Dmitry: Tolya, deixe-me dar um exemplo simples: vetorização. Com a vetorização no .NET, tudo fica muito ruim, apesar do System.Numerics.Vectors estar sendo serrado lentamente. E o que isso leva, da minha parte, por exemplo? O fato de que, se você estiver vasculhando o mercado e comprando uma biblioteca matemática para .NET, ela será escrita pelos profissionais (com um invólucro completo). Como no .NET praticamente não há acesso à aceleração de hardware (AVX, etc.), ele está agora em algum estágio embrionário.

Anatoly: Os intrínsecos são lançados no .NET Core 3, onde você pode acessar diretamente o AVX. Eles realmente estão na infância, mas existem coisas básicas e o resto é bastante emocionante.

Dmitry: Você entende, temos 2019 no quintal. Como usuário de todo esse bem matemático acelerado, não esperei por isso. E, como resultado, para mim, se eu quiser considerar algo rapidamente, o C # não é mais um candidato. Porque as bibliotecas C ++ já existem. Talvez o tempo já tenha sido perdido para isso.

Anatoly: Parece-me que o C # está se movendo na direção de vantagens, está tentando conquistar seu mercado. Mas as vantagens não estão mais se movendo para lugar algum.

Sergey: De onde isso vem? O que significa "vantagens não vão a lugar nenhum"?

Anatoly: Quando eles me dizem em 2019 que haverá iteradores no padrão, haverá algum progresso sobre lambdas, parece-me que ...

Sergey: Não sei por que você está falando sobre iteradores e lambdas, não entendo de que maneira a pedra era ...

Anatoly: Não sobre iteradores, eu coloquei errado, eu quis dizer os inúmeros contêineres que discutimos antes. Enquanto isso, temos uma correspondência de padrões.

Sergey: Tudo depende se é necessário ou não. Estamos discutindo a correspondência de padrões. Mas até agora não há argumentos sobre se é necessário nos profissionais.

Dmitry: eu ouço muitos comentários semelhantes das vantagens, que dizem que "embora já exista uma presença óbvia dessa ou daquela abordagem em outros idiomas, ela já foi elaborada, as pessoas adoram e desenvolvem soluções, ainda não queremos isso em vantagens, porque não são vantagens idiomáticas ". E parece-me que Java caiu no mesmo buraco. Java disse "não, pessoal, não teremos delegados". E em Java ainda não há conceito de delegados, mas no .NET tudo isso funciona bem.

Sergey: Olha, os profissionais são muito simples. Mais uma vez, de volta ao comitê. Há uma dica - são pessoas que estão desenvolvendo compiladores. E para eles, as palavras "abstração de custo zero" são exatamente o que devem ser orientadas. E a palavra "legado", infelizmente.

Dmitry: Bem, a abstração de custo zero é um montador. Se queremos abstração de custo zero em geral, precisamos escrever tudo no assembler.

Sergey: Não há abstração.

Dmitry: Assembler é uma abstração sobre código binário. É apenas a segunda geração, não a terceira.

Sergey: Então, sobre todos os tipos de "coisas convenientes", verifica-se que não está claro como fazê-las funcionar rapidamente.

Dmitry: Deixe-os trabalhar mais devagar. A idéia com iteradores assíncronos, corotinas, tudo isso - no .NET com C # a palavra-chave yield não sabe mais quantas versões funcionam muito bem. Sim, enormes máquinas estatais estão sendo construídas nos bastidores, apenas mágica. Mas assíncrono / espera também cria mágica e em iteradores. Mas todo mundo usa, e é realmente conveniente.

Sergey: Coroutines adicionam vantagens, olá.

Dmitry: Bem, sim, está sendo feito progresso. Mas as corotinas estão aparecendo agora, não há 10 anos.

Sergey: Mais uma vez. As vantagens são mais antigas e, na minha opinião, a velocidade de desenvolvimento diminui com o acúmulo da base de código. Claramente, tudo depende se existe um desejo de manter o suporte ao Legado. Para os profissionais, esta é uma posição de princípios. Ou seja, o código que você escreveu nos anos 80 agora é compilado por um compilador moderno.

Dmitry: Sim, mas você compila o código que escreveu no C # 1.0 com um compilador moderno.

Sergey: Isso não é verdade. No início da discussão, eu disse que uma atualização chegou nas minhas primeiras versões do .NET e, de repente, todos os programas pararam de funcionar.

Dmitry: Talvez as APIs que você usou tenham mudado. Aqui você precisa separar a biblioteca e a linguagem de programação.

Sergey: Eu não tinha nada, apenas C #. Eu era jovem, esses foram os primeiros anos.

Dmitry: Lembro-me de apenas uma mudança no C # 4 - uma pequena mudança no comportamento do foreach. Obviamente, nas versões 1.x tudo poderia ser mais turbulento, mas agora definitivamente não estamos na fase em que alguém quebra algo de repente.

Anatoly: Bem, oficialmente a Microsoft adere à posição que monitora estritamente a compatibilidade com versões anteriores, eles testam novas versões em um grande número de máquinas e bases de código. Talvez você tenha um bug ou algo parecido.

Dmitry: Em geral, o .NET também monitora a compatibilidade com versões anteriores, mas a velocidade do progresso aumentou tanto o C ++ quanto o Java.

Sergey: Parece-me que desempenhou um grande papel, que a princípio tudo isso foi impulsionado por uma empresa. Como o C ++ estava originalmente no comitê - e isso é política, todo mundo está tentando tomar uma decisão - e isso é como uma reunião do Senado em Guerra nas Estrelas.

Dmitry: Então seu argumento é que somos todos reféns dos comitês que não são movidos pela inovação?

Sergey: O problema é que você não escolhe uma solução que satisfaça a todos. A ferramenta é tão amplamente distribuída que é usada por muitas empresas. Vocês lembraram as mesmas corotinas: por que as receberam tarde? Porque a Microsoft, ao que parece, não pôde concordar com o Google. Havia duas implementações - não me lembro quem estava por trás da pilha e quem estava por trás da pilha, mas não podia concordar. Como as duas empresas são grandes, elas têm enormes bases de código que já contêm uma solução e se recusam a reescrevê-la.

Dmitry: Do ponto de vista do leitor, a pessoa terá a sensação de que cuspiu nele de uma torre sineira alta, porque há interesses corporativos, eles estão envolvidos em interlovers, e tudo isso não parece lhe interessar - vá, lacaios, "deixe-os comer bolo" .

Sergey: Muito pelo contrário. O comitê está tentando escolher para que uma pessoa comum não precise sofrer. E muitas vezes é difícil.

Dmitry: Bem, posso dizer por mim mesmo que não sofrerei se o custo zero for direto para algum lugar, mas haverá algum tipo de oportunidade flexível de caminhar pela árvore binária e iterar de maneiras diferentes sem variáveis ​​de tempo. yield, - - — , , , , - .

: , , , , - .

: , Boost .

: , . Boost , , , … - . std::string, , . size(), length(), : , - ? - , , . , . , , , . , , , - .




: , , , . ?

: , , «», .

: .

: embedded-, include, ?

: . embedded -.

, , - ? , , . ?

: . 150 . - , . .

: , !

: , Steam, , , 64 . , 150 ?

: , , .

: , -. ? , , , — , zero cost abstractions . -?

: , , , , ?

: , . , , .

: , , , . — , . , . , , . , . -. C.

: . «». : , . , , , . . , .

: , . . , . proposal. .

: , proposal. , « »: , STL , . , - , .

: STL . STL . , , STL — , , .

: , — , ? , greenfield. brownfield development, . — , . — . ?

: , . , , . , . , , . G++ , Clang . .

: , , , . « , A, B». , .NET, . , , , , , ?

: , , . , C++ 2.0. ++C++. , C.

: , . , , . , , , , #include #import - — . , . , , , , .

. , . , , , C# C++, .

: , , 10 . , , , , , , . « », . , .

C# , C++. , C# . , , . , , , , JIT' — , , - ( int). , , , , .

: , , , C# — . , , C++ . , . ( , ) — cutting edge. , UI- C++, , . C# — . C++ , .

, . , , , C++ , , , . , .

, C# Microsoft. , .NET Foundation, , , Microsoft. , .



C++ Russia DotNext . : ?

Source: https://habr.com/ru/post/pt469467/


All Articles