É comum prototipar em uma linguagem de nível superior? [fechadas]

18

Atualmente, estou brincando com a idéia de iniciar um projeto que excede em muito minha capacidade atual de programação em uma linguagem na qual tenho muito pouca experiência no mundo real (C). Seria valioso prototipar em uma linguagem de nível superior com a qual eu estou mais familiarizado (como Perl / Python / Ruby / C #), apenas para que eu possa dar continuidade ao design geral?

Por fim, o produto final é sensível ao desempenho (é um mecanismo de banco de dados), daí a escolha de C, mas receio que não conhecer C bem me fará perder a floresta para as árvores.

Enquanto procurava por perguntas semelhantes, notei um colega mencionar que os programadores costumavam prototipar no Prolog e depois montá-lo no assembler.

Mark Canlas
fonte
4
Já ouvi falar de pessoas que escreveriam assembler primeiro codificando o que queriam em C, depois desmontando-o e ajustando manualmente o assembly resultante.
user16764
9
Não se esqueça que o desempenho geralmente se resume a corrigir a seleção e a implementação de algoritmos, escrevendo código paralelo para problemas paralelos embaraçosos e boas representações de dados. Não se preocupe com C até obter o design correto.
Peter Smith
1
@ user16764: Realmente fiz isso. Exceto que o idioma era Fortran. Mas nós ajustamos manualmente a saída do compilador exatamente como você descreve.
S.Lott
C não é necessariamente mais rápido. Especialmente se o desempenho estiver vinculado a IO. Mesmo para desempenho vinculado à CPU, se você não é um especialista em C, uma VM otimizada provavelmente pode superar o que você escreve.
Jiggy #
Costumo usar essa técnica de prototipagem: um problema é expresso em sua linguagem mais natural, que acaba sendo implementada como uma DSL. Então, quando o protótipo estiver concluído, em vez de recodificar uma parte DSL em uma linguagem de nível inferior, melhorarei a implementação deste compilador DSL, até que o desempenho seja aceitável.
SK-logic

Respostas:

27

Usar C não torna seu aplicativo automaticamente mais rápido. Quando você tiver a capacidade de escolher uma linguagem de programação diferente para sua plataforma, eu recomendo.

Como Bill Harlan afirmou :

É mais fácil otimizar o código correto do que corrigir o código otimizado . A otimização prematura realmente dificulta a otimização a longo prazo. A otimização desnecessária distorce os projetos, destrói a modularidade e oculta as informações e torna o código muito mais difícil de modificar. Os erros latentes levam mais tempo para serem encontrados. Muitas vezes descobrimos por criação de perfil, ou alterando máquinas ou compiladores, que julgamos mal o esforço computacional do nosso código. Adivinha? Agora, a otimização é muito mais difícil do que deveria ser.

Se você realmente pode prever problemas de desempenho, considere usar C ++. palavras cprogramming.com muito bem :

Você pode se perguntar, no entanto, se vale a pena dar-se a reutilização de C ++ para obter o pequeno aumento no desempenho com C, especialmente quando lata C ++, se necessário, ser escrito em um estilo de programação C .


Para responder melhor à sua pergunta real: eu escreveria o código em um idioma de nível superior, não apenas o criaria protótipo, e otimizaria apenas em idiomas de nível inferior quando encontrar problemas de desempenho.

Steven Jeuris
fonte
25
+1: Além disso, Perl, Python e Ruby podem chamar funções C, para que você possa escrever as partes sensíveis ao desempenho em C, se necessário.
Larry Coleman
Eu prototipei o código de visão de máquina em Java; o que acabou por ser rápido o suficiente. Recodificação em C teria sido muito fácil (você acabou de escrevê-lo como C; usando a antipattern fixação primitiva)
Tim Williscroft
Eu escrevi código em tempo real em Java. Nesse projeto em particular, o acesso ao arquivo foi feito com C ++ e o código em tempo real estava em Java - louco! No entanto, o código em tempo real foi incrivelmente rápido. Não foi muito complicado, mas lidou com quantidades incríveis de dados em nenhum momento. Então, eu diria que você pode definitivamente usar linguagens de alto nível para aplicativos sensíveis ao desempenho.
Configurator
@ Tim Williscroft: Eu só pareço aparecer nesta mesma página quando busco no Google por "antipattern de fixação primitiva". O que é isso?
SingleNegationElimination
@TokenMacGuy: obsessão primitiva tem mais hits (mesmo antipattern)
Tim Williscroft
7

Não seria valioso fazer isso, porque a) as partes daqueles idiomas que se traduzem diretamente para C não seriam mais simples eb) as partes que não se traduzem diretamente para C seriam mais difíceis de reescrever em C do que se você os tivesse escrito em C em primeiro lugar.

user16764
fonte
+1 - Especialmente porque seria difícil mudar o código OO para C se você não estiver familiarizado com o idioma ou tornaria o uso da linguagem de alto nível mais complicado se você escrever de maneira processual.
21711 Jetti
Sim, exatamente. Estou preocupado que ainda possa estar pensando em conceitos mais elevados que não são facilmente traduzidos para C, como se eu usasse muita mágica ou açúcar.
precisa
4

Esta não é uma pergunta com uma resposta sim ou não categórica. Permita-me pesar com uma anedota.

Exemplo 1

Fui encarregado de portar um jogo escrito em Java para o Flash, AS3. Na superfície, isso tem o potencial de ocorrer de forma relativamente suave. Afinal, você pode considerar esse trabalho mais claro do que o trabalho médio de um cliente, porque você já possui uma especificação funcional completamente integrada na forma do jogo de origem. Java e AS 3 são linguagens de alto nível, e o AS3 compartilha muitos traços em comum com Java, como estruturas de pacotes, herança única / interface múltipla, digitação forte (opt-in) e noções de variável pública / protegida / privada e declarações de função. Naquela época, eu ainda era muito verde em Java e completamente novo na base de código-fonte original. Então eu apenas mergulhei para ver o que eu poderia encontrar esperando que fosse rápido e fácil.

Como se viu, o autor do código tentou criar um mecanismo abstrato que pudesse ser transportado do Java para outro ambiente indefinido. Isso me deu esperança de que seria fácil portar. Infelizmente, o que eu descobri foi que estava olhando para a perspectiva de reinventar o Flash em cima do Flash, sem o benefício dos Threads. Uma porta literal, como se viu, seria simplesmente uma má idéia ... um pesadelo de desempenho. Além disso, o jogo implementou sua própria linguagem de script externa personalizada, o que significaria criar um analisador e um lexer para essa linguagem, se eu esperasse usar todos os arquivos de dados de origem originais.

No final, dadas as restrições de tempo e orçamento, o código fonte original não ajudou muito. A parte mais útil de tê-lo foi que eu sabia imitar com precisão o fluxo de controle da lógica do jogo ... mas eu realmente precisava da fonte original para isso? Provavelmente não.

Mas esse exemplo pode não ser tão relevante porque é o inverso da sua situação. Eu esperava usar uma base de código que não escrevi, em um idioma que não conhecia na época para acelerar o desenvolvimento em um ambiente que eu conhecia bastante. Então, aqui está um exemplo diferente

Exemplo 2

Observando o que o desenvolvedor Java estava tentando criar uma base de código portátil, comecei a fazer algo parecido comigo no meu trabalho em Flash ... escrevendo código que não dependia tanto de estender as classes flash.display. *, Por exemplo, e usando composição para criar visualizações. Não confiei tanto no flash.event. * E, em vez disso, escrevi um sistema leve de passagem de mensagens, não vinculado particularmente a um idioma ou plataforma. Recentemente, terminei um jogo usando o referido framework e queria ver se seria fácil portá-lo para C # (uma linguagem que eu conheço tanto quanto parecida com Java e AS3) como um projeto Unity 3D. Como se viu, isso foi muito mais bem-sucedido! Como penso com mais fluência no AS3 do que no C #, ter os algoritmos já escritos economizou uma tonelada de tempo. Tudo o que eu precisava fazer era simplesmente mudar a sintaxe, que não é '

Portanto, apenas na minha própria experiência pessoal, não posso dizer que a resposta sempre será sim ou não. Você deve levar em consideração o quão dependente de idiomas específicos de idioma está na sua língua de alto nível de escolha e se a recriação desses idiomas será fácil ou difícil em C.

scriptocalypse
fonte
Sua segunda história ilustra como me sinto. Eu tentaria manter a implementação do protótipo genérica e sem truques / truques, de modo que a maioria, se não todas, as idéias possam ser traduzidas para C. É mais fácil falar do que fazer, mas acho que em um nível alto o suficiente ainda é possível. Obviamente, o diabo está nos detalhes.
Mark Canlas
@ Mark Canlas "o diabo está nos detalhes." Absolutamente. Acho que é possível que sua primeira tentativa dê errado, se você nunca portou código entre idiomas ou ambientes antes, apenas porque é difícil prever todos os problemas em potencial até encontrá-los.
scriptocalypse
2

Eu acho que seria valioso começar com pseudocódigo. Escrever um protótipo em outro idioma parece um potencial desperdício de tempo, já que seu idioma de nível superior provavelmente não será traduzido para 'C' tão bem quanto o pseudocódigo.

Além disso, usando o pseudocódigo, você desenvolverá uma melhor compreensão de como seu sistema realmente funciona.

Durante o mesmo período em que você está trabalhando no pseudocódigo, você deve estudar C. Em seguida, quando terminar o planejamento, você poderá estar pronto para realmente implementar a coisa.

Como o motivo proposto para escrevê-lo em outro idioma foi para ajudar no andamento do design, você pode usar alguns diagramas UML ou algo dessa natureza para começar.

Casey Patton
fonte
2

Você pode criar um protótipo do algoritmo - resolver os erros de design da lógica principal, usando definitivamente uma linguagem de "nível muito alto" (digamos, Matlab, talvez Ruby). Use-o para provar que seu algoritmo funciona e funciona corretamente, depois implemente-o do zero em uma linguagem de "baixo nível".

Você não ganhará muito se escolher C ++ ou mesmo Java ou C # como "nível alto" e C como "nível baixo" porque o ganho na legibilidade não será significativo e a "tradução" ainda será bastante dolorosa e bastante problemática. propenso. A idéia é a essência, o mecanismo do seu projeto na implementação de alto nível não deve ocupar mais que uma tela ou duas, ser fácil de entender, fácil de ler e todas as advertências serem dolorosamente óbvias - essencialmente, um bloco funcional e executável diagrama.

SF.
fonte
2

Um mecanismo de banco de dados trata principalmente de lidar com E / S de baixo nível da maneira ideal e lidar com estruturas complexas, como árvore b e listas vinculadas de forma eficiente.

Portanto, é definitivamente um problema em C / C ++, embora haja algumas implementações Java muito boas por aí.

Desenvolver algoritmos corretos com bom desempenho é muito mais fácil em uma linguagem de nível superior. Geralmente é o caso de tentar várias variações e comparar os resultados. Você pode traduzir o algoritmo "vencedor" para C.

Uma solução de compromisso pode ser escrever a implementação inicial em uma das linguagens JVM de nível superior (Jython, Groovy vem à mente) e depois mover classe por classe para Java quando a implementação estabilizar.

James Anderson
fonte
2

Eu não acho que seja comum, mas está feito. Um dos arquitetos mais afiados com quem trabalhei costumava fazer sua modelagem em Python e depois implementar esse código em C ++.

Em geral, para fazer isso valer a pena, acho que você realmente precisa executar algoritmos complexos e altamente otimizáveis, que não são facilmente expressos de maneira direta no idioma de destino. Para a maioria das situações do "mundo real / comercial", é relativamente fácil expressar a intenção de alto nível no mesmo idioma que estamos alvejando e uma implementação nesse idioma atende aos nossos requisitos de desempenho, para que não haja necessidade / desejo de modelar em um nível mais alto. linguagem de nível.

Dada a sua situação, onde você tem um conhecimento melhor de uma linguagem de nível superior, eu pude ver essa metodologia funcionando bem no curto prazo. Não apenas fornecerá um roteiro para manter as coisas no caminho certo, mas se você tiver perguntas, poderá fazer com maior precisão.

user29776
fonte
1

Atualmente, estou trabalhando em um projeto que está escrito em C "por causa do desempenho" (essa foi a motivação original), mas, na verdade, se analisado, revela que ele passa a maior parte do tempo esperando por outros sistemas (um banco de dados, outros aplicativos escritos em Java, "eventos" em um soquete).

Se você usar o algoritmo errado, também obtém desempenho ruim em C (por exemplo, se você faz uma pesquisa linear por uma chave ", como C não possui tabelas de hash e não queremos usar outras bibliotecas", você fica mais lento do que se você faça isso com uma linguagem que possua tabelas de hash ou similares como C ++, Java, C #, Python ... e assim por diante).

Se você é forçado a fazê-lo em C por qualquer motivo, então a criação de protótipos em outro idioma que você conhece não é uma má idéia apenas se você prototipar sabendo quais "problemas" você terá na implementação real de C, isso é difícil se você não está confiante com C. (em breve descobrirá, por exemplo, que bibliotecas C / C std não possuem contêineres, apenas uma matriz "simples"; você precisa de bibliotecas não std). Além disso, C não é OO; portanto, se você estiver fazendo prototipagem de maneira OO, será mais difícil.

Resumindo, a melhor coisa a fazer é executar a implementação real na linguagem de "prototipagem" e, se realmente necessário, escrever funções intensivas da CPU em C, mas se apenas C for aceitável, aprenda-a melhor antes de fazer o protótipo em outro idiomas e, é claro, antes de escrever a implementação.

ShinTakezou
fonte
1

Existem muitos aplicativos críticos de desempenho, escritos em uma linguagem de nível superior.

Eu programei em Assembler e C no passado, e embora seja legal sentir-se tão perto do metal, seu uso é muito limitado hoje em dia.

Há tantas coisas que atrapalham o desempenho, que duvido que você chegue à parte em que a própria linguagem é o fator limitante. Isso está considerando que é C vs C #.

Digamos que você obtenha um aumento de desempenho de 10% a 15% pelo idioma. Isso não é nada comparado às ordens de magnitude que aumentam a implementação do algoritmo correto.

Ao programar em C #, você terá muito mais tempo para se concentrar na arquitetura e implementação de algoritmos / estruturas de dados, levando a melhores otimizações de nível superior.

No mundo real, você sempre fica com tempo limitado, portanto, gaste seu tempo na parte certa do projeto.

Boris Yankov
fonte
0

Estou curioso para saber qual é o seu plano para criá-lo em C? Você vai criar um protótipo e aprender C e depois codificá-lo novamente em C? Para mim, isso parece um pouco com os proverbiais "olhos sendo maiores que o estômago", que eu acho que muitos programadores ficam presos enquanto aprendem novas tecnologias (eu sei que tenho). O que quero dizer é que você está tentando projetar algo que é claramente sensível ao desempenho sem ainda conhecer os meandros da linguagem na qual você acha que ela precisa ser escrita. Basicamente, você deseja começar a projetar um aplicativo C antes de começar. conheça C quando o tempo pode ser melhor gasto aprendendo C primeiro e, em seguida, você poderá obter mais informações sobre como escrever o aplicativo que deseja. Talvez eu tenha confundido a pergunta e você pretende entregá-la a outro programador para criar o programa em C,

programmx10
fonte
Às vezes "não faça isso". é a resposta correta para "Como faço para X?"
Larry Coleman
0

A prototipagem é feita, às vezes, para entender o problema que você está tentando resolver. E, às vezes, conhecer as tecnologias subjacentes, se você ainda não estiver familiarizado com ela.

Para o caso mencionado, você está pensando em criar um protótipo em uma linguagem de script, por exemplo, python e criar o código real em C.

Avaliando algumas possibilidades:

1 . Você protótipo em python e escreve o software em C.

A criação de protótipos em uma linguagem de script pode ajudar onde você deseja rapidamente verificar a saída em relação à entrada . Isso é útil se você precisar testar principalmente a sua lógica para resolver um problema. Além disso, é útil se você deseja montar rapidamente uma demonstração para outras pessoas.

Qualquer código que você escreveu em python não será usado no software final. Mas isso pode ajudar se você estiver passando seu protótipo para alguém que possa ler python e escrever em C. Aqui, a prototipagem pode ajudar a comunicar uma ideia .

Este método é apropriado para testar a viabilidade lógica da solução.

2 . Você protótipo em C e escreve o software em C.

A prototipagem em C, que é nova para você, tem duas vantagens. Um, enquanto você escreve o protótipo, você começa a entender as partes relevantes da língua , biblioteca, API, armadilhas, etc. Dois, enquanto você construir o software final, você pode começar a partir do protótipo em si o que poupa tempo e reutiliza código .

Esse método é adequado para testar a viabilidade lógica e tecnológica da solução.

3 . Você pode considerar maneiras de não codificar o protótipo, dependendo do problema em questão.

Se algum pedaço de lógica e idéias você deseja criar protótipo; pseudo-código , fluxogramas e diagramas de blocos no papel também são bons.

Se for um protótipo de interface do usuário, considere alguma ferramenta de maquete da interface do usuário ou, novamente, algum documento.

Amol
fonte
0

Eu acho que você deve criar um protótipo em um idioma que você esteja familiarizado (Pytho / Ruby / C # e não) para que:

  1. Você tira o máximo proveito das instalações / bibliotecas fornecidas pelo idioma.
  2. Você gasta seu tempo decidindo sobre as opções de design em vez das limitações de idioma.

Mais tarde, você pode usar uma ferramenta de criação de perfil para encontrar áreas do gargalo da garrafa. Reimplemente em C / C ++. Repita o passo acima algumas vezes, quem sabe seu protótipo pode ser 'rápido o suficiente'!

KGA
fonte
0

Não acho que você esteja ganhando nada com a abordagem que descreveu, e várias pessoas descreveram o motivo com alguns detalhes.

Um projeto em que estive envolvido utilizou esse tipo de abordagem: desenvolvimento de biblioteca matemática para as arquiteturas Cell / BE e Power7. As funções foram modeladas em Haskell (usando CoCoNUT) e as funções de saída estavam em montagem otimizada para uma arquitetura de destino específica.

Nesse caso, os objetivos eram alto desempenho com instruções de montagem ajustadas e a capacidade de direcionar várias arquiteturas.

Comida para, espero que você não morra de fome :)

Stephen
fonte
0

Para um mecanismo de banco de dados de alto desempenho, você provavelmente precisará:

  • multiencadeamento,
  • gerenciamento explícito de memória,
  • notificações assíncronas,
  • semáforos ou primitivas de sincronização,
  • acesso fácil às funções de baixo nível do sistema de arquivos.

Os algoritmos que você escolhe são críticos para o desempenho.

O conselho geral é começar com um idioma de alto nível e migrar apenas os bits que precisam ser otimizados para um idioma de nível inferior.

No entanto , o idioma de alto nível escolhido deve ser capaz de suportar os algoritmos que você precisa escrever: os algoritmos eficientes aqui podem ser dominados pelo controle do encadeamento, pelo uso eficiente da memória e pelo uso das melhores operações de sistemas de arquivos de baixo nível acessível. Portanto, se o objetivo final for o desempenho, não será possível criar protótipos em idiomas que não suportam os primitivos que você precisa usar.

Se você precisar testar seu protótipo (ou outras pessoas precisarem desenvolver software contra suas interfaces), também precisará trabalhar em uma linguagem que suporte as APIs pretendidas. Você pode permitir que outras pessoas testem seu código e realizem seus próprios testes de regressão enquanto otimizam.

Essas considerações provavelmente descartam muitos idiomas para a criação de protótipos de alto nível nesse caso - e provavelmente todos os que você mencionou (exceto possivelmente C #). Mas você pode, é claro, pseudocódigo em qualquer idioma (incluindo inglês) e, se necessário, pode prototipar partes do projeto (funções de classificação, por exemplo) no seu idioma preferido.

A estreita relação entre C ++ e C (e diferenças desprezíveis de desempenho) significa que existem muito poucas razões para não preferir C ++ a C no produto final.

(Estou respondendo no pressuposto de que você precisa de um mecanismo de banco de dados de alto desempenho para uma finalidade específica: se suas intenções são mais modestas, presumivelmente, você estaria escolhendo um mecanismo existente da prateleira).

MZB
fonte
-2

Eu acho que a fama de C é bem merecida, porque o magnífico produto Unix foi escrito em C. No entanto, comparado às pessoas que conhecem C melhor, eu sou bastante cético sobre o porquê de usá-lo. Dizem que Ken Thompson (depois de escrever a primeira versão do Unix em linguagem assembly) começou a escrever o Unix no Fortran, mas desistiu após uma semana ou um mês e começou a usar o C que estava sendo desenvolvido por seu colega Ken Ritchie na o mesmo tempo.

Fiquei surpreso ao ler recentemente que o Fortran é mais rápido que C e C ++.

Richard Mullins

richard mullinsq
fonte
1
Como isso responde à pergunta?
gnat