O código científico é um domínio diferente o suficiente para ignorar padrões comuns de codificação?

21

Ultimamente, tenho tentado me lembrar do seguinte fato.

Por um lado, há uma série de diretrizes e padrões de codificação para o que é considerado código "saudável", "limpo", "bem escrito" e assim por diante. Veja o "Código Limpo" que parece ser amplamente discutido aqui também. Regra de exemplo: métodos de 7 linhas e 1 ou 2 níveis de indentação. De alguma forma, espera-se que o código que não segue morra de baixa manutenção.

Por outro lado, trabalho com OpenCV, OpenCascade, VTK, etc. É um código científico. Eles têm métodos de 2 páginas (sen eu mesmo), o OpenCascade possui um método ou uma classe dividida em 10 arquivos (sem brincadeiras aqui), o VTK também é uma bagunça às vezes. No entanto, esses projetos prosperam, são mantidos e amplamente utilizados!

Onde está o problema? Temos permissão para escrever códigos científicos e com muita matemática de uma maneira que funcione, e podemos mantê-lo? Existe um conjunto separado de padrões para esses projetos, se houver?

Pode ser uma pergunta ingênua, mas estou no que parece ser um vazio de programação, tentando criar um conjunto de regras sobre como fazer e não fazer as coisas, que é a maneira como fui ensinado a trabalhar no ensino médio. Desde que me formei, quase não tive apoio de diretrizes com as coisas que tive que fazer, principalmente a programação - ninguém se incomoda em ensinar isso.

iksemyonov
fonte
25
Não, não é, mas a maioria dos cientistas não tem o treinamento em engenharia para conhecer melhor.
Gort the Robot
4
Em qualquer projeto que já existe há algum tempo, você encontrará uma tonelada de código mal escrito, mas que parece funcionar bem o suficiente para que ninguém se preocupe em voltar e limpá-lo. Às vezes, isso ocorre porque os padrões e padrões evoluem com o tempo, às vezes, porque os padrões não foram aplicados de maneira uniforme; às vezes, é muito mais divertido adicionar novas funcionalidades do que voltar e refatorar um pedaço de código que funciona, mas é pouco documentado.
23416 Justin Cave
2
@ JustinCaveL Ou: "Se não estiver quebrado, não conserte". Especialmente aplicável ao código somente gravação . Veja também plaza.ufl.edu/johnaris/PDFs/ProblemSolvingFlowChart.pdf
Robert Harvey
Você certamente vai encontrar o meu anterior pergunta relevante: programmers.stackexchange.com/q/266388/620
rwong
8
Para outros respondentes: Esta pergunta refere-se à base de código das bibliotecas de código aberto para tarefas computacionalmente intensivas em um ou mais domínios científicos . Esta pergunta não é sobre código descartável. Faça uma pausa por um momento para ter certeza de entender todos os aspectos destacados antes de escrever uma resposta. Obrigado.
rwong

Respostas:

28

O código científico é um domínio diferente o suficiente para ignorar padrões comuns de codificação?

Não, não é.

O código de pesquisa geralmente é "descartado" e escrito por pessoas que não são desenvolvedores por experiência, por mais fortes que sejam suas credenciais acadêmicas. Alguns dos códigos de pesquisa que escrevi me faziam chorar . Mas funcionou!

Uma coisa a considerar é que os porteiros dos projetos conduzem o que é incluído. Se um grande projeto começou como um projeto de código acadêmico / de pesquisa, acaba funcionando e agora está uma bagunça, alguém precisa tomar a iniciativa de refatorá-lo.

É preciso muito trabalho para refatorar o código existente que não está causando problemas. Especialmente se for de todo o domínio específico ou não tiver testes. Você verá que o OpenCV possui um guia de estilo muito abrangente, mesmo que não seja perfeito. Aplicando isso retroativamente a todo o código existente? Isso não é para os fracos de coração.

Isso é ainda mais difícil se todo esse código funcionar. Porque não está quebrado. Por que consertar isso?

No entanto, esses projetos prosperam, são mantidos e amplamente utilizados!

Esta é a resposta, em certo sentido. O código de trabalho ainda é útil e, portanto, é mais provável que seja mantido.

Pode ser uma bagunça, especialmente inicialmente. Alguns desses projetos provavelmente começaram como um projeto único que "nunca precisaria ser reutilizado e poderia ser jogado fora".

Considere também que, se você estiver implementando um algoritmo complexo, pode fazer mais sentido ter métodos maiores, pois você (e outras pessoas familiarizadas com o lado científico) pode conceitualmente entender melhor o algoritmo. Meu trabalho de tese foi relacionado à otimização. Ter a lógica do algoritmo principal como um método era consideravelmente mais fácil de entender do que estaria tentando separá-lo. Certamente violou a regra "7 linhas por método", mas também significou que outro pesquisador poderia examinar meu código e entender mais rapidamente minhas modificações no algoritmo.

Se essa implementação fosse abstraída e projetada bem, essa transparência seria perdida para não programadores .

Para outros respondentes: Esta pergunta refere-se à base de código das bibliotecas de código-fonte aberto para tarefas computacionalmente intensivas em um ou mais domínios científicos. Esta pergunta não é sobre código descartável. Faça uma pausa por um momento para ter certeza de entender todos os aspectos destacados antes de escrever uma resposta.

Eu acho que as pessoas geralmente têm a idéia de que todos os projetos de código aberto começam como "ei, eu tenho uma ótima idéia para uma biblioteca que será muito popular e usada por milhares / milhões de outras pessoas" e, em seguida, todo projeto acontece assim.

A realidade é que muitos projetos são iniciados e morrem. Uma porcentagem ridiculamente pequena de projetos "chega" ao nível do OpenCV ou VTK etc.

O OpenCV começou como um projeto de pesquisa da Intel. A Wikipedia descreve como parte de uma "série de projetos". Seu primeiro lançamento não beta foi em 2006, ou sete anos após o início. Suspeito que o objetivo inicialmente era versões beta significativas, não código perfeito.

Além disso, a "propriedade" do OpenCV mudou significativamente. Isso faz com que os padrões mudem, a menos que todas as partes responsáveis ​​adotem exatamente os mesmos padrões e os mantenham durante o projeto.

Devo também salientar que o OpenCV já existia há vários anos antes da publicação do Manifesto Ágil, a partir do qual o Clean Code se inspira (e o VTK quase 10). O VTK foi iniciado 17 anos antes da publicação do Clean Code (o OpenCV era "apenas" 9 anos antes).

enderland
fonte
2
Eu tenho usado o OpenCV em 2004 e foi horrível. A Willow Garage (novos proprietários ) fez um ótimo trabalho convertendo quase tudo em C ++. Na verdade, é uma das poucas bibliotecas científicas que consistem em bom código.
Nimcap 23/03
15

Os cientistas não são desenvolvedores. O trabalho deles não é escrever código por si só. O trabalho deles é resolver problemas, e a programação é apenas uma das ferramentas que eles podem usar.

A maioria dos códigos empresariais criados por desenvolvedores profissionais, como eles se autodenominariam, é uma bagunça. A maior parte desse código não usa padrões de design ou os utiliza incorretamente. A maioria dos comentários é candidata ao TheDailyWTF . Portanto, como em nosso próprio setor, vemos resultados de pessoas cujo trabalho é escrever código, o que você esperaria de pessoas cujo trabalho não é escrever programas?

Todas as práticas que um desenvolvedor profissional real aprende durante sua carreira beneficiariam um cientista? Absolutamente. Seria possível para todo cientista passar de cinco a dez anos de sua vida aprendendo o desenvolvimento de software? Provavelmente não. Portanto, a qualidade do código é como é.

Outro fator é a cultura. Se seus pares não escrevem código limpo, por que você faria? Como ninguém se importa, você não está realmente disposto a fazer um esforço extra.

Finalmente, a maioria dos códigos científicos tem uma vida útil relativamente curta. Você escreve o código para uma pesquisa específica e, quando a pesquisa é concluída, você não o reutiliza. Depois de adquirir esse hábito, é difícil fazer a diferença entre bibliotecas reutilizáveis, como as que você cita e o código descartável.

Arseni Mourzenko
fonte
"O trabalho deles não é escrever código em si. O trabalho deles é resolver problemas" - observe que tecnicamente o trabalho de um desenvolvedor também não é escrever código. Seu trabalho, assim como o cientista, é resolver problemas. Estou excluindo fábricas de software e macacos de código que são pagos para manter as cadeiras aquecidas, mas por definição eles também não se importam muito com código limpo, portanto não são relevantes para esta questão :)
Andres F.
8

Ignorar? Não. Re-considerar e ajustar? Certo. Muitos códigos científicos exigem muita matemática e são críticos para o desempenho. Coisas como a sobrecarga de chamadas de função podem realmente se tornar um problema; portanto, você pode acabar com estruturas mais profundamente aninhadas do que em um aplicativo comercial típico. Isso não significa que você deve mergulhar de cabeça em mil micro-otimizações. Você ainda deve se concentrar em escolher o algoritmo certo e fazer otimizações apenas cujos efeitos você pode medir.

Algumas das diferenças são óbvias e triviais. As diretrizes de codificação normalmente exigem a escolha de nomes significativos de variáveis ​​e nomes com uma única letra serão imediatamente suspeitos. Um aplicativo científico ainda desejará nomes de variáveis ​​significativos, mas às vezes o nome mais significativo será uma única letra, referindo-se a uma variável em uma equação conhecida.

Charles E. Grant
fonte
4
+1 para o comentário de nomeação de variável. Quando eu estava na escola, fiz codificação freelance para vários departamentos, e nos departamentos de estatística e matemática fui "fortemente encorajado" a usar nomes de variáveis ​​como Aje T0porque é assim que as variáveis ​​foram nomeadas nas funções que eu estava traduzindo para código. Usando algo como correlationIndexou startTimevocê iria se queixar.
TMN
4

Todas as respostas existentes abordaram essa questão de forma abrangente. No entanto, gostaria de salientar qual é o verdadeiro antípoda entre os gostos do OpenCV etc., versus, digamos, o código desenvolvido de acordo com as boas práticas de negócios (código completo, código limpo, SOLID, etc.)

Em geral, há muitos benefícios comerciais para o código-fonte ser o KISS - "mantenha as coisas simples, estúpidas". Há também um YAGNI relacionado - "Você não vai precisar".

Infelizmente, para softwares intensivos em computação nos domínios científicos, o código-fonte raramente é simples ou enxuto .


Tradicionalmente, o OpenCV sofria de falta de generalizações (muita duplicação de código para suportar opções diferentes), enquanto o VTK sofria de generalizações excessivas (modelos).

Nos primeiros dias, certas partes do OpenCV foram originalmente desenvolvidas em C. Mais tarde, o OpenCV adotou a API C ++ que conhecemos hoje. Alguns algoritmos são reescritos para aproveitar as interfaces C ++ (classes base abstratas) e modelos C ++. Outros algoritmos eram simplesmente invólucros para o código C original. Restos desse código podem ser encontrados espalhados no módulo "imgproc".

O OpenCV contém muita programação SIMD (vetorização). Até essa data, a programação SIMD em C ++ ainda requer o uso de intrínsecas (intel.com) , (arm.com) .

Os intrínsecos do SIMD são parecidos com a linguagem assembly, exceto que o compilador cuida da atribuição de registro de variáveis ​​e o compilador tem liberdade para trocar a ordem das instruções por ganhos de desempenho. Os algoritmos escritos para usar intrínsecos do SIMD tiveram um alto custo de manutenção. Foi por isso que mencionei uma pergunta que fiz anteriormente - Custo de manutenção da base de código de programação SIMD .

Uma pessoa que não está fazendo programação SIMD pode facilmente ser levada a acreditar que o SIMD pode ser encapsulado de maneira elegante e que a programação SIMD de baixo nível não deve mais ser necessária. Isso é realmente muito longe da verdade. Desafio qualquer um a tentar implementar um algoritmo útil no SIMD (não fractais) e ver a dificuldade de uso nesses encapsulamentos propostos.


Abaixo está uma longa lista de idéias quando tento analisar por que o software computacional não pode ser o KISS ou o YAGNI. No entanto, todas essas idéias são generalizações excessivas e parecem não apoiar a observação acima.

Os principais fatores contribuintes são:

  • Desempenho do software
  • A necessidade de suportar muitas opções e trocas de algoritmos
  • A necessidade de suportar diferentes plataformas e compiladores de hardware
    • Isso se soma ao problema de desempenho do software - o desempenho precisa ser bom para muitas plataformas e compiladores de hardware.
  • A falta de modernização contínua da base de código , devido à falta de recursos, falta de pessoas com conhecimento que possam melhorar a qualidade do código sem comprometer os outros fatores, etc.
    • Projetos de código aberto sofrem com a tragédia dos bens comuns .
    • Projetos de código aberto que recebem doações tinham que atender a entregas específicas - a qualidade do código normalmente não faz parte dela.
    • Em particular, existe até uma falta de pessoas conhecedoras que podem fazer ou sugerir melhorias incrementais na qualidade do código . Esse é o problema dos "olhos perdidos" - muitas pessoas se beneficiam do código, mas poucas demoraram a ler o código.
  • Falta histórica de portas de qualidade de código , como revisão de código, testes de unidade, análise estática, etc.
    • Para um projeto em larga escala, esses portões de qualidade de código não são apenas etapas manuais - cada um exigiria uma infraestrutura (um sistema baseado na Web, um sistema de teste de unidade, um sistema de automação de construção etc.)

Vários dos fatores contribuintes acima são antípodas no desenvolvimento de software comercial:

  • Normalmente, o software comercial não precisa lidar com as mesmas altas taxas de transferência de dados vistas no software computacional.
  • O software comercial pode ser vinculado a um único sistema operacional e arquitetura de computador.
  • O software comercial pode ser frugal ao decidir quais funções incluir. De fato, o desenvolvimento de software de negócios incentiva os gerentes a dizer não aos novos recursos, a menos que haja um bom caso de negócios.
    • Os usuários do software interno de negócios podem ser treinados para fazer as coisas de maneira diferente, evitando a necessidade de fazer alterações no código.
    • Se um software comercial perde um cliente devido a um recurso ausente, mas conquista dois novos clientes devido à simplicidade e facilidade de uso aprimoradas (consulte "O Paradoxo da Escolha" ), no geral, é um ganho líquido - é uma boa coisa que esta característica está faltando.
  • O software de negócios é suportado por um fluxo de receita contínuo, para que ele possa gastar parte dele na modernização contínua da base de código.
rwong
fonte
1
Você está trazendo muitos pontos para a mesa que parecem irrelevantes para a questão.
Martin Maat
@ MartinMaat Se você tem coisas positivas a acrescentar a esta pergunta, escreva em sua própria resposta.
Rwong
3

O código científico é um domínio diferente o suficiente para ignorar padrões comuns de codificação?

Depende do que você chama de "padrões comuns de codificação". Eu não chamaria os extremos de Agile de "comuns". Em particular, considerar uma função com oito linhas muito longa ou com mais de dois níveis de indentação muito complexa são padrões ridículos no campo da programação numérica / científica.

Uma função de matriz de tempos de matriz muito simples tem mais de sete linhas e possui três níveis de recuo. A função se tornará consideravelmente mais complexa do que se deveria se preocupar com eficiência. Essa é uma operação tão comum que a eficiência é importante. Quebrá-lo em pedaços é exatamente o que você não quer fazer. Uma decomposição da matriz será ainda mais complexa.

David Hammen
fonte
2
"Agile" não tem nada a ver com padrões de codificação.
Gort the Robot
@StevenBurnap - Claro que sim. Veja o "Código Limpo". Possui vários padrões de codificação.
David Hammen 17/03/16
1
Código limpo com muitos padrões de codificação é um argumento ruim. O manifesto do Agile pode não ter nada a ver com os padrões de codificação, mas o Agile promove flexibilidade e responde a mudanças e a aderência aos padrões ou às práticas recomendadas de codificação. Portanto - de uma maneira muito indireta e cautelosa, o ágil pode não ter nada a ver com os padrões de codificação, mas o padrão de codificação tem muito a ver com o ágil.
Marjan Venema
1

Decidi postar isso como uma nova resposta, porque é uma perspectiva completamente diferente.

Vamos dar uma olhada em um exemplo de código que considero "código limpo" em termos de visão por computador e entendimento de imagem:

https://github.com/opencv/opencv/blob/05b15943d6a42c99e5f921b7dbaa8323f3c042c6/modules/photo/src/seamless_cloning_impl.cpp

Para aqueles familiarizados com MATLAB e computação científica, o código em C ++ é quase tão conciso quanto o código MATLAB mais limpo possível.


Agora temos que perguntar: por que toda a base de código da biblioteca (OpenCV neste exemplo) não é gravada no mesmo padrão que essa amostra de código?


Devemos estratificar a base de código de uma grande biblioteca científica em níveis de abstração .

No nível baixo , você está literalmente reimplementando adições e subtrações. Ou, literalmente, re-mapeando cada operação para as implementações mais rápidas em cada plataforma.

https://github.com/opencv/opencv/blob/master/modules/core/src/hal_replacement.hpp

O nível intermediário é onde encontramos o código "mais sujo", no qual são gastos entre 80% e 90% do tempo de execução da CPU. (Da mesma forma, talvez 80% - 90% do esforço de desenvolvimento foram gastos no nível intermediário, se considerarmos separadamente os esforços de desenvolvimento de software da pesquisa científica.)

No alto nível , temos o código mais limpo, escrito por pesquisadores.


É necessária uma forte excelência na organização do código-fonte para garantir que esses níveis não se misturem. Isso está além dos padrões de codificação , mais tem a ver com administração de código aberto .

Por exemplo, às vezes é tomada a decisão de dividir um projeto de código aberto em dois. Você não pode fazer essas coisas acontecerem por confirmações de código.

rwong
fonte