Tive uma conversa breve e incomum com um arquiteto sênior sobre linguagens dinâmicas e estáticas. Ele disse que os dados da empresa mostram que há evidências de maior produtividade quando são usadas linguagens estáticas. Observe que é uma grande empresa com longa história. Para minha surpresa (e outras), a métrica que ele usou foi adicionar linhas de código.
Ele rapidamente descartou objeções em relação à métrica, dizendo que em uma mesma empresa, com cultura, linha de negócios e dados suficientes, as diferenças (quanto a situações e capacidades únicas dos indivíduos) se misturam o suficiente para que a métrica SLOC seja útil para comparar a produtividade de ferramentas e linguagens.
Embora eu não ache que essa afirmação seja apoiada por uma análise estatística rigorosa, há alguma evidência no setor que apoiaria essa linha de pensamento?
fonte
Respostas:
O argumento do arquiteto sênior pode significar duas coisas.
Pode significar que um desenvolvedor médio da empresa produz mais linhas de código ao usar linguagens estáticas do que ao usar dinâmicas. Por exemplo, se quinze desenvolvedores trabalham com Java por seis meses, eles escreverão 100 KLOC, e se os mesmos quinze desenvolvedores trabalharem com Python por seis meses, eles escreverão apenas 50 KLOC.
Não há correlação entre LOC e produtividade aqui. E se forem necessárias quatro vezes mais linhas de código em Java para produzir o mesmo recurso que em Python? Se isso for verdade, o uso do Python resultaria em duas vezes a produtividade, com base nas métricas do KLOC acima.
Ele também pode significar que um desenvolvedor médio na empresa produz menos linhas de código ao usar linguagens estáticas do que ao usar linguagens dinâmicas: quinze desenvolvedores escreveriam em seis meses 100 KLOC em Java ou 200 KLOC em Python.
Embora menos linhas de código geralmente sejam melhores (menos código para escrever, ler e manter), ainda não está claro quantos recursos os desenvolvedores Java produziram em comparação aos Python. Talvez eles tenham escrito meias linhas de código em comparação com os desenvolvedores de Python, mas também tenham produzido metade do número de recursos?
Nos dois casos, o LOC não é uma métrica valiosa, porque o mesmo recurso não seria traduzido na mesma quantidade de linhas de código em idiomas diferentes . Algumas línguas tendem a ser mais detalhadas; outros - mais compactos. Embora em alguns casos a compactação seja valiosa, não há regra geral para isso. Um exemplo extremo seria a linguagem Brainfuck, que possui extrema compacidade, mas que não é popular por sua legibilidade. Comparar linguagens semelhantes pode ser complicado: por exemplo, quando se trata de chaves, o Java segue o estilo K&R, enquanto em C #, a chave de abertura fica em sua própria linha na maioria dos casos, quando segue o estilo oficial, o que leva a uma falha artificial. aumento de LOCs para C #. E o que acontece quando se compara uma linguagem processual com uma linguagem orientada a objetos ou com uma linguagem funcional?
Em vez de usar uma métrica propensa a erros, o arquiteto sênior pode confiar em um grupo de métricas que medem a produtividade quando usadas em conjunto: o número de recursos desenvolvidos por mês, o número de bugs introduzidos na base de código e o tempo gasto na solução desses bugs. , a evolução da dívida técnica etc. Essa comparação pode ser complicada no início, pois é preciso levar em consideração o desconhecimento da equipe com o novo idioma. Uma vez que a equipe se familiarize o suficiente, a escolha deve se basear nas métricas estáveis, bem como, em grande parte, na preferência dos próprios membros da equipe.
LOC tem um valor em algumas situações estreitas. Por exemplo, poderia dar uma dica sobre o tamanho do projeto e partes do projeto (e, em média, se correlaciona com os pontos de função, embora seja mais fácil de medir) ou pode indicar os métodos e classes que podem precisar de mais atenção, porque do seu tamanho grande. No entanto, o LOC deve ser usado com cuidado, uma vez que é mal utilizado com frequência por pessoas que imaginam alguma correlação entre coisas não relacionadas. O uso mais humanamente desastroso de LOCs foi no passado a tentativa de medir a produtividade de um desenvolvedor individual com base nos LOCs escritos por mês.
fonte
Sobre produtividade e SLOC
O problema com o SLOC
O problema com a métrica SLOC é que ela mede uma aproximação da quantidade de código gravado, sem levar em consideração:
Em outras palavras, a produção de código espaguete não-sustentável, suscetível a erros e com muitas peças coladas, será considerada mais produtiva do que o código reutilizável cuidadosamente projetado.
Portanto, o SLOC definitivamente não é a melhor maneira de medir a produtividade.
Que produtividade estamos considerando?
A produtividade é medida para um processo. Portanto, o SLOC pode ser um indicador perfeitamente válido apenas para o processo de codificação.
Se, por exemplo, você não entende os requisitos ruins, gasta cinco meses para produzir o software, mostra ao usuário, descobre que está errado e gasta mais 5 meses para reescrevê-lo para o zero, você teria a mesma produtividade no SLOC / mês, uma equipe que escreveu o código logo na primeira vez, por exemplo, porque usou um processo ágil que reduz mal-entendidos por meio de feedback frequente. Essa produtividade aparentemente aparente esconde enormes problemas.
Portanto, medir a produtividade do desenvolvimento de software precisa levar em consideração todo o processo, incluindo a análise de requisitos, o design do código, a codificação, o teste, a depuração e a verificação de que as expectativas do usuário são atendidas. Como todas essas atividades são muito diferentes, o melhor é medir o único pensamento que importa: software em funcionamento, ou seja, o que o software produzido significa para o usuário .
Como medir as entregas de software?
Existem várias abordagens:
Sobre a produtividade da digitação estática versus dinâmica
Tenho que confessar que sou pessoalmente fã de linguagens de tipo estaticamente, porque no meu íntimo sei que é mais confiável (anos de codificação me provaram isso).
Então, uma coisa que eu tenho certeza é que a linguagem de tipo estaticamente é capaz de evitar muito mais erros / bugs em tempo de compilação (por exemplo, erros de digitação, incompatibilidade nos tipos esperados, etc ...) do que as línguas de tipo não estaticamente. Mas, com toda objetividade, eu não ousaria generalizar abusivamente isso como uma produtividade mais alta.
Seu arquiteto está certo?
Talvez talvez não.
Mas seus argumentos não parecem válidos: o ganho de produtividade da linguagem de tipo estaticamente vem de um número significativo de erros que são detectados antecipadamente pelo compilador.
Consequentemente, não é possível descobrir esse ganho "mais alto" de produtividade observando apenas o SLOC sem observar o retrabalho necessário para linguagens de tipo dinâmico. Portanto, a comparação dele não pode ser justa.
O argumento de circunstâncias comparáveis também não é válido. Algumas linguagens de tipo dinâmico permitem algumas construções de nível superior que exigem menos código do que fazer o mesmo em uma das linguagens de tipo estaticamente clássicas. Portanto, você pode precisar de menos tempo, escrever menos código, mas adicionar a mesma sobrecarga de análise, teste e verificação. Portanto, medir a produtividade pelo SLOC diluiria os possíveis ganhos de produtividade, criando assim um viés contra a linguagem digitada dinamicamente.
Algum estudo para apoiar essa afirmação?
Existem vários estudos acadêmicos recentes sobre o tema. Embora alguns deles vejam uma vantagem da digitação estática, em geral se limita a uma finalidade específica (documentação, reutilização de código ou API mal documentado, etc.). As palavras prudentes também são usadas porque o IDE moderno reduziu significativamente os riscos relacionados à digitação dinâmica:
fonte
Aqui está um contra-exemplo para seu arquiteto sênior: Suponha que eu queira escrever uma hierarquia de três classes, duas das quais derivam da terceira, implementando algumas funções virtuais que a classe base define.
Se eu escrever essas três classes em C ++, isso é bastante simples. Declaro as aulas, uso virtual nos locais corretos e pronto.
Se eu escrever essas três classes em C, precisarei adicionar um pouco de código: preciso definir
struct
s para as tabelas v, preciso adicionar um ponteiro da tabela v à classe base, preciso adicionar código para os construtores para realmente definir os ponteiros da tabela v, preciso adicionar código aos construtores para chamar o construtor da classe base, preciso adicionar código para executar a alocação de memória explicitamente antes de chamar um construtor (o que o C ++new
faz em uma única etapa ), da mesma forma, preciso separar a destruição dafree()
chamada subsequente e assim por diante.O ponto é que todas essas coisas adicionais são bastante irracionais. Eu posso fazê-los muito rapidamente. Portanto, não levarei muito mais tempo para escrever a versão C do que preciso para escrever a versão C ++. No entanto, produzi muito mais linhas de código C que código C ++. Tanto que pareço ter sido mais produtivo em C em termos de SLOCs.
Qualquer idioma que exija alguma quantidade de código padrão aparecerá mais produtivo em termos de SLOCs do que um idioma que não exija a mesma quantidade de código padrão.
Veja, o argumento SLOC é tão fundamentalmente defeituoso, que eu realmente consideraria o contrário: eu diria que "os programadores tendem a produzir mais SLOCs em linguagens estáticas" para significar: "linguagens estáticas parecem exigir mais código padrão e, assim, reduzir a produtividade ".
fonte
Eu serei o contrário.
Acompanhamos o SLoC em nosso trabalho (embora não o usemos diretamente nas decisões de pessoal), e já tive pessoas discutindo o que a maioria das pessoas está dizendo em suas respostas. De fato, "LoC não importa, porque a tecnologia X nos permite fazer mais com menos código" ou "Melhores desenvolvedores escrevem códigos melhores e mais curtos e, portanto, não escrevem mais do que ninguém". Na minha experiência (embora eu não tenha números concretos para apoiar essas coisas), essas objeções simplesmente não estão corretas. No meu tempo, vi uma correlação clara na taxa e na qualidade da produção de código para nossos desenvolvedores, quando comparada com todas as outras medidas significativas de sua "competência" geral como engenheiro. Para dar alguns contra-exemplos aos tipos de argumentos apresentados acima:
Essa parte final é o meu resumo geral, BTW. O que descobri é que, independentemente da pilha de tecnologia ou tipo de projeto, a maioria dos desenvolvedores tem seu próprio ritmo, que é o ritmo em que operam. Se um idioma possui muitos recursos que tornam os desenvolvedores mais eficazes, isso é um grande benefício para os negócios, mas isso não significa que eles escreverão menos código como resultado. Em vez disso, eles realizam os recursos mais rapidamente e passam rapidamente para o novo código. Novamente, o resultado final é que eles avaliam em que codificam depende principalmente de suas habilidades e menos de sua pilha de tecnologias. De fato, por causa disso, eu geralmente esperaria que a pilha de tecnologia fizesse mais diferença na taxa na qual os tickets e recursos são desenvolvidos do que na taxa na qual as pessoas codificam.
Dito isto, nem a taxa de redação de código nem a taxa de fechamento de tickets são uma medida perfeita de produtividade, e é por isso que não tomamos diretamente decisões de equipe com base no SLoC. Em vez disso, faz parte do processo, e as avaliações dos funcionários são feitas usando o maior número possível de dados. Eu diria que seu arquiteto certamente não é louco.
Uma exceção
A única exceção com a qual concordo é a possibilidade do código da placa da caldeira. Se houver muita copiar e colar de uma classe (ou outra) para colocá-la em funcionamento, isso obviamente distorcerá as métricas. Isso também é verdade se você tiver ferramentas que podem gerar automaticamente grandes quantidades de código para você. No entanto, acho que essas serão frequentemente a exceção e não a regra. Se seus desenvolvedores gastam algum tempo copiando o código da placa da caldeira para começar, você está usando o conjunto de tecnologias errado. Se eles estão realmente escrevendo o código, mesmo que seja bastante repetitivo, espero que isso incline qualquer medida apenas uma pequena quantidade: ao escrever código, na maioria das vezes estamos limitados à rapidez com que podemos pensar no problema. do quão rápido podemos digitar. Mesmo ao escrever um código relativamente repetitivo,
Obviamente, tudo acima é baseado em minha própria experiência pessoal. Sua milhagem pode variar e, obviamente, sou minoria. Sinta-se livre para discordar. Em resumo, porém:
Acho que a taxa de codificação depende mais da rapidez com que você consegue pensar nos seus problemas do que em qualquer outra coisa. Como resultado, descobri que a taxa de codificação é uma medida decente de produtividade, mesmo em conjuntos de tecnologia, com apenas algumas exceções possíveis.
fonte
Embora eu esteja pulando na onda. Eu acho que o impacto no comportamento dos programadores precisa ser destacado.
Usar o SLOC como uma medida produtiva tem um efeito tóxico no moral do programador. No momento em que qualquer engenheiro da sua equipe / empresa percebe que é medido no SLOC, várias coisas acontecem:
Não posso enfatizar com força o quão corrosivo é projetar o moral, como já vi acontecer duas vezes em duas empresas diferentes. Quaisquer que sejam os casos de uso aparentemente válidos que você possui, eu argumento que é improvável que valha a pena o impacto em sua equipe / empresa, mesmo que haja apenas uma pequena chance de que seu uso seja descoberto. Embora em alguns casos haja uma correlação entre o número de linhas escritas e a quantidade de recursos úteis, incentive todos os comportamentos errados nos seus programadores e envie a mensagem de que a qualidade não é importante.
fonte
Geralmente, não é considerado uma maneira válida de medir a produtividade. Código menor geralmente é melhor que código maior; portanto, um desenvolvedor mais produtivo geralmente produz menos código. A produtividade é a maior atingida na depuração; desenvolvedores eficientes gastam pouco tempo depurando.
Linguagens de tipo estático são mais produtivas (se você controlar todas as outras diferenças entre as linguagens), porque, quando usadas com sabedoria, reduzem o tempo de depuração, detectando erros na fase de compilação, onde são mais rápidos de corrigir.
fonte
A única métrica que você pode usar para comparar a produtividade de desenvolvedores entre idiomas é uma métrica que não compara o código entre os idiomas. Alguns idiomas são notoriamente detalhados (COBOL para a vitória herdada) e outros requerem várias etapas para fazer algo que você pode fazer em uma linha de código (assembly vs. praticamente todo o resto). Mesmo se você comparar apenas linhas de código ativas (ou seja, não conte declarações e conte apenas código que tenha alguma ação envolvida), você ainda poderá distorcer seus resultados.
Você pode argumentar a favor das taxas de mudança. Ou seja, linhas de código adicionadas, comparando a inclinação da produtividade no mesmo período. No entanto, isso não leva em conta alterações negativas nas linhas de código. Por exemplo, você herda um projeto que possui código de copiar e colar em qualquer lugar. Você realiza refatorações rápidas e fáceis para reduzir o número de blocos de código repetidos - por definição, você tem uma inclinação negativa.
Trabalhei em um projeto em que a infraestrutura era muito frágil e as ferramentas estavam desatualizadas. O projeto foi construído em Java com um aplicativo de página única, mas hospedado em um contêiner de portlet sem nenhum benefício aparente. O tempo que levou para fazer mudanças simples foi ridiculamente longo. Se você basear todas as suas conclusões nesse projeto específico, poderá concluir que o Java era ruim ou os Aplicativos de Página Única eram ruins. Nem são verdadeiras. O sistema que o feio projeto deveria substituir foi criado em C # e WebForms. Quando criamos o caso de negócios para estender o aplicativo existente para atender às necessidades dos clientes, nossa produtividade disparou. Isso significa que um aplicativo WebForms fortemente acoplado é superior? Você só pode concluir esse caso em particulare não se estende ao mundo em geral. E isso só faz sentido porque havia um aplicativo existente com maturidade suficiente para estender.
Mesmo a comparação das taxas de itens resolvidos no sistema de rastreamento de problemas é falha no sentido de que você está comparando infraestruturas completas do projeto entre si. As bibliotecas e estruturas usadas podem acelerar ou retardar o progresso. Você pode estar na fase inicial com muito pouca inércia a ser superada, onde o projeto "melhor que" está em uma fase de manutenção em que o número de novos tickets é relativamente baixo. Nunca é um caso de comparar coisas semelhantes.
fonte