É comum não usar bibliotecas para algoritmos numéricos padrão e por quê?

54

Muitos algoritmos numéricos (integração, diferenciação, interpolação, funções especiais etc.) estão disponíveis em bibliotecas de computação científica, como GSL . Mas muitas vezes vejo código com implementações "roladas manualmente" dessas funções. Para pequenos programas que não são necessariamente destinados à distribuição pública, é prática comum entre os cientistas da computação implementar apenas algoritmos numéricos (com o que quero dizer copiar ou transcrever de um site, Receitas Numéricas ou similares) quando você precisar deles? Nesse caso, existe um motivo específico para evitar a vinculação a algo como GSL, ou é apenas mais "tradição" do que qualquer outra coisa?

Eu pergunto porque sou um grande fã da reutilização de código , o que sugere que eu deveria tentar usar implementações existentes sempre que possível. Mas estou curioso para saber se existem razões para que esse princípio seja menos valioso na computação científica do que na programação geral.


Esqueci de mencionar: estou perguntando especificamente sobre C e C ++, em oposição a linguagens como Python, onde há um benefício claro (velocidade de execução) em usar uma biblioteca.

David Z
fonte
14
Por um lado, você não gostaria de reinventar a roda. Por outro lado, a melhor maneira de entender um algoritmo (e por extensão, diagnosticar facilmente casos em que o algoritmo falha espetacularmente) é tentar codificar uma implementação por conta própria.
JM
2
Você reprova todos os teoremas que encontra? Talvez você tente e brinque com alguns casos de bebês, mas, a menos que seja o foco de sua pesquisa, você provavelmente o aceita e segue em frente com a vida.
quer
3
Os físicos não são programadores e não estão acostumados a lidar com o código de outras pessoas (lendo ou corrigindo). Quando eles precisam usar o código de outras pessoas, geralmente não é um código muito bem escrito ou bem comentado, escrito por outros físicos, aumentando novamente a ideia de que é melhor reescrevê-lo do que reutilizá-lo. Isso é verdade pelo menos em alguns campos / comunidades, mas as atitudes estão mudando entre os mais jovens. Mas nem tudo é ruim, pense na atitude do mau aluno de CS que não pode fazer algo se não encontrar uma biblioteca fácil o suficiente para isso.
Szabolcs 14/05

Respostas:

45

Eu costumava implementar tudo sozinho, mas ultimamente comecei a usar muito mais as bibliotecas. Eu acho que existem várias vantagens muito importantes no uso de uma biblioteca, além da questão de saber se você deve escrever uma rotina ou não. Se você usa uma biblioteca, obtém

  • Código que foi testado por centenas / milhares / mais usuários
  • Código que continuará sendo atualizado e aprimorado no futuro, sem nenhum trabalho de sua parte
  • Código otimizado que é mais eficiente e talvez mais escalável do que o que você escreveria em uma primeira tentativa
  • Dependendo da biblioteca, ao estabelecer uma interface para ela em seu código, você poderá acessar muitos algoritmos que não usa no momento, mas que deseja no futuro

No último ponto acima, estou pensando em grandes bibliotecas como Trilinos ou PETSc . Eu posso reforçar isso com alguns exemplos pessoais concretos no desenvolvimento do PyClaw . Embora tivesse sido fácil paralelizar o Clawpack com as chamadas MPI, optamos por usar o PETSc. Isso nos permitiu limitar o código paralelo no pacote a menos de 300 linhas de Python, mas, melhor ainda, ao colocar nossos dados no formato do PETSc, obtivemos acesso imediato aos solucionadores implícitos do PETSc, permitindo o trabalho atual em um solucionador implícito no PyClaw. Como segundo exemplo, o PyClaw inicialmente incluiu a reconstrução WENO de quinta ordem com código de mão, mas finalmente decidimos confiar no PyWENOpacote para isso. Foi um grande ganho, pois o PyWENO pode gerar automaticamente rotinas WENO de qualquer ordem em vários idiomas.

Por fim, se você usar bibliotecas, poderá contribuir de volta desenvolvendo melhorias ou localizando bugs, o que beneficiará muitas outras pessoas, enquanto a depuração ou aprimoramento do seu próprio código apenas o beneficia.

David Ketcheson
fonte
5
"você pode contribuir de volta desenvolvendo melhorias ou encontrando bugs, o que beneficiará muitas outras pessoas." - isso satisfaria tanto o desejo de "mexer / aprender" quanto a preguiça (não ter que fazer coisas que já foram feitas). :)
JM
11
Veja também casos de borda. Para muitos algoritmos, é trivial implementar algo que "funcione", mas que não lida corretamente com uma minúscula sub-fração de casos. Isso pode ser bom para um projeto pequeno, mas não posso contar o número de vezes que fui atropelado por uma condição patológica em algo que eu mesmo "otimizei".
meawoppl
34

Existe uma sobrecarga substancial do programador envolvida na vinculação a uma função de biblioteca, especialmente se essa biblioteca for nova para o programador. Geralmente, é mais simples reescrever algoritmos simples do que descobrir as especificidades de uma biblioteca específica. À medida que os algoritmos se tornam mais complexos, esse comportamento muda.

O Python se destacou em reduzir essa sobrecarga com ferramentas como pip / easy_install e uma interface uniforme de estrutura de dados (ou seja, toda biblioteca parece pegar e produzir uma matriz numpy).

MRocklin
fonte
19

Um dos projetos nos quais estou envolvido agora é escrever um pacote flexível de simulação e análise para uma classe de detectores de física de partículas. Um dos objetivos deste projeto é fornecer a base de código a ser usada nessas coisas nas próximas décadas.

Neste ponto, já temos duas dúzias de dependências, tornando o processo de construção um pesadelo que gerou um projeto separado gerenciado fora do centro de computação Fermilab, apenas para fornecer uma cadeia de ferramentas confiável.

Agora imagine que você encontra a necessidade de alguma ferramenta que não esteja nessa cadeia de ferramentas (aconteceu comigo no mês passado). Você tem três escolhas

  1. Roll você possui. Com todos os riscos e aborrecimentos que envolve.
  2. Raspe algum código de uma biblioteca em algum lugar e inclua-o no The Project. Isso significa que você precisa executar a manutenção daqui para frente e que precisará entender o código de outra pessoa quando isso acontecer.
  3. Vá até as pessoas que mantêm a cadeia de ferramentas, implore pelo que você precisa e aguarde um ciclo de liberação para obtê-lo. Esses caras são bem receptivos, mas você precisa defender isso sem trabalhar com código ou depois de fazer (1) ou (2).

É muito fácil escolher (1). Talvez seja fácil demais.

dmckee
fonte
Sim, dependências adicionadas são uma desvantagem significativa do uso de bibliotecas.
David Ketcheson
Dependências é a grande desvantagem em minha mente bem
fomite
2
É possível que minha resposta esteja colocando muito peso no fato de dependências e não o suficiente no processo burocrático de obter o anúncio aprovado de dependências instalado em grandes projetos.
precisa
* seu no ponto 3. (Desculpe pelo nitpick.)
299792458 23/01
ER não. Diz o que eu quero dizer.
dmckee
12

Eu acho que é bastante comum, com alguns algoritmos com maior probabilidade de serem reimplementados do que outros.

Há uma troca complicada entre quão irritante é instalar uma biblioteca, quão difícil é implementar o algoritmo você mesmo, quão difícil é otimizá-lo e quão bem a biblioteca se adapta às suas necessidades. Além disso, às vezes o uso de uma biblioteca é apenas um exagero: usei o algoritmo de bissecção lenta em um dos meus programas porque o chamei apenas algumas vezes e não queria adicionar uma biblioteca apenas para isso.

É fácil escrever uma versão bem otimizada? Se for, pode ser melhor fazê-lo. Você conseguirá exatamente o que precisa e não dependerá do trabalho de ninguém. Mas é claro que você realmente precisa saber o que está fazendo: mesmo algoritmos simples podem ser difíceis de implementar.

Eu ficaria curioso para ver um estudo sobre isso, mas, da minha perspectiva tendenciosa, os cientistas costumam usar bibliotecas para álgebra linear e geradores de números aleatórios, com a maior parte do código restante sendo caseiro.

PhDP
fonte
12
"Mas é claro que você realmente precisa saber o que está fazendo: mesmo algoritmos simples podem ser difíceis de implementar." - isso não pode ser enfatizado o suficiente.
JM
10

Eu acho que implementar um algoritmo em vez de usar uma biblioteca pode às vezes dar uma melhor compreensão e controle do modelo. Quando estou codificando algum programa para cálculos científicos, é importante entender o que estou fazendo. A implementação de algoritmos importantes me ajuda a obter um melhor conhecimento do problema e a obter um melhor controle dele.

Por outro lado, às vezes não é uma tarefa trivial selecionar uma biblioteca necessária para obter uma solução; portanto, é melhor procurar algoritmos já implementados quando você tiver certeza do que está tentando alcançar e por que deseja.

Se os algoritmos forem complexos, codificá-los manualmente oferece a oportunidade de melhorar o desempenho / qualidade da solução usando recursos específicos da tarefa. E, às vezes, é necessário alterar um pouco o algoritmo, o que é mais fácil se você souber o código que escreveu e poderá editá-lo da maneira que desejar.

gmk
fonte
11
+1 para melhorar a compreensão. Embora isso seja mais um problema para seus próprios algoritmos do que para uma rotina de biblioteca.
Faheem Mitha 12/12
8

Uma resposta é que existem tantas variações leves no código numérico que é realmente difícil encapsular isso em uma biblioteca. Considere isso em comparação com o software da Web, que geralmente é fácil de instalar e possui um conjunto claro de entradas e saídas. Eu acho que mais comum são as pessoas pegando uma estrutura, ou uma grande biblioteca que funciona como uma estrutura (Trilinos / PETSc), e usando esse ecossistema para obter os benefícios do uso de códigos comunitários.

aterrel
fonte
7

Antes de decidir se deve ou não usar bibliotecas, acho que você também gostaria de descobrir o quanto o uso de uma biblioteca ajudará seu código. Se você estiver usando uma biblioteca bem otimizada para um kernel computacional chave, provavelmente é muito mais eficiente do que tentar escrever o seu próprio.

No entanto, se você estiver escrevendo uma rotina especializada que será chamada apenas uma vez durante a execução de um programa, pode não valer a pena adaptar seu código para se adequar à estrutura exigida por uma biblioteca.

(Outra coisa a se pensar: quanta reestruturação você precisará fazer para tirar proveito da biblioteca? A menos que as horas de trabalho que você gaste para corrigir o código sejam compensadas pelos ganhos correspondentes em eficiência ou precisão numérica, talvez não vale a pena a longo prazo. Idealmente, porém, isso é algo que você planeja ao projetar inicialmente estruturas e algoritmos de dados, para que o "fluxo" da biblioteca seja levado em consideração desde o início.)

aeismail
fonte
6

Meus 2 centavos.

Eu acho que é mais fácil escrever geralmente sobre isso, ao invés de apenas sobre C / C ++. Primeiro, bibliotecas em linguagens como Python não são necessariamente usadas para obter um benefício de velocidade, mesmo que isso seja uma consequência. Acho que o @David cobriu muito bem os motivos.

Levando isso de cima, a implementação da linguagem, em certa medida, determina a quais bibliotecas você tem acesso. Linguagens comumente usadas na ciência computacional incluem C, C ++, Python, Perl, Java, Fortran e R. Exemplos menos comuns podem ser Ocaml e Common Lisp. Agora, como a maioria dessas linguagens é escrita em C, elas possuem uma interface de função estrangeira natural para C. No entanto, não é tão fácil chamar, por exemplo, uma biblioteca Perl do Python ou vice-versa. Portanto, na prática, as pessoas tendem a

  1. Use uma biblioteca escrita em sua linguagem de implementação, geralmente algo que faça parte das bibliotecas padrão ou esteja amplamente disponível ou

  2. Chame uma biblioteca C / C ++ através dos idiomas FFI. Isso pressupõe que um wrapper ainda não exista, pois, se existir, não será facilmente distinguível de (1).

(2) geralmente é mais difícil, porque você precisa envolver a função C / C ++. Além disso, você deve agrupar a biblioteca ou adicionar uma dependência extra. Por esse motivo, é mais provável que as pessoas usem as bibliotecas de idiomas internas, em vez de usar GSL, por exemplo, que está em C.

Para rotinas muito genéricas, por exemplo, gerar amostras aleatórias a partir de distribuições ou rotinas numéricas básicas como quadratura de integrais, é fácil e comum reutilizar alguma biblioteca. À medida que a funcionalidade que estamos tentando implementar se torna mais complexa, torna-se exponencialmente mais improvável que se encontre a função exata que se deseja em outra biblioteca e, mesmo que se faça, pode-se gastar muito tempo pesquisando e finalmente adaptando a função como necessário (o estilo / design do código pode ser um problema, por exemplo). E, como discutido acima, é possível acessar apenas um subconjunto das bibliotecas existentes. Por outro lado, implementar um algoritmo sozinho, se ele for complexo e não o foco principal, pode ser assustador e, é claro, é preciso lidar com esses problemas de velocidade incômodos.

Portanto, isso se torna um problema de otimização na análise de custo / benefício. Minha experiência é que, mesmo para técnicas comparativamente padrão como o MCMC, eu geralmente acabo escrevendo meu próprio código, porque ele se encaixa melhor na maneira como estou projetando o software geral.

Obviamente, mesmo que você não use o código, é possível aprender com o código de outras pessoas. Mas não sei quantas vezes os cientistas se preocupam em fazer isso. Minha impressão é que ler o código de outras pessoas para aprender é mais uma coisa de engenheiro de software.

Faheem Mitha
fonte
6

Pensando no meu curso de mecânica do segundo ano, me ocorre que parte da razão pela qual eu implementei minhas próprias versões de algoritmos conhecidos é que fui ensinado a fazê-lo dessa maneira. Não consigo pensar em um único exemplo em que me ensinaram como fazer interface e vincular uma biblioteca na minha graduação em física. Tenho uma boa lembrança de ver pela primeira vez uma lista de coordenadas de uma bola de golfe girando, tendo calculado a solução das equações de Newton acopladas no FORTRAN. Há uma certa emoção e satisfação (até orgulho) que advém do cálculo das coisas do zero.

JxB
fonte
11
Este é certamente um fator. E esse foco em fazer você mesmo é necessário para uma parte da educação de um cientista computacional. Os programadores puros são nocauteados em algum momento, mas nós, tipos científicos, podemos passar dessa sala de aula introdutória para um projeto povoado quase exclusivamente por outras pessoas que seguiram o mesmo caminho.
dmckee
5

Eu acho que se deve usar bibliotecas testadas, tanto quanto possível. A maioria das pessoas não é especialista em computação numérica e provavelmente não será capaz de implementar uma solução tão correta e cuidadosamente quanto o que está disponível em bibliotecas bem testadas. Dito isto, no entanto, às vezes é o caso de não haver bibliotecas disponíveis que implementem a combinação de recursos necessários em um determinado aplicativo. Eu já vi isso acontecer na área técnica em que trabalho; os códigos existentes não resolveram todos os casos e alguém acabou implementando um solucionador do zero.

mhucka
fonte
11
Se a biblioteca não atender a todas as suas necessidades, recomendo que você estenda o código da biblioteca e envie um patch. Dessa forma, você beneficiará muitos outros com seu trabalho, e outros também testarão seu código para você. Obviamente, isso pressupõe que o código da biblioteca tenha sido escrito de uma maneira suficientemente flexível para que possa ser estendido para atender às suas necessidades.
David Ketcheson
Concordo, é uma ótima solução, e algo que as pessoas devem fazer se possível.
Mhucka
5

O problema fundamental está geralmente na interface entre o aplicativo e a biblioteca. Um programador de aplicativos tem conhecimento sobre o problema que geralmente é perdido ao passar o problema (por exemplo, como uma matriz) para uma biblioteca. Esse conhecimento é tal que explorá-lo mais do que compensa os benefícios do uso da biblioteca altamente otimizada. Como resultado, o programador de aplicativos "rola" sua própria implementação que explora o conhecimento.

Assim, uma biblioteca realmente boa precisa que esse conhecimento seja passado do aplicativo para a biblioteca, para que a biblioteca também possa tirar proveito dela.

Robert van de Geijn
fonte
3

Além de tudo o que já foi dito acima, repetirei minha resposta da pergunta "Fortran vs C ++": O ativo mais valioso que um programador possui é seu tempo. Sim, dependências externas geralmente são estranhas. Mas gastar tempo para reimplementar, depurar e testar algoritmos que outros já implementaram é quase sempre estúpido, e o resultado raramente será tão bom quanto o código que foi escrito por especialistas em um tópico específico. Reutilize o que os outros fizeram!

Wolfgang Bangerth
fonte
Eu dou minha própria resposta sobre esse tópico. Você pode aprender muito mais quando reescreve todos os detalhes. Eu trabalho por 5-6 anos com nuvens de pontos agora. Nos primeiros três anos, eu mesmo escrevi todas as funcionalidades. Passei a segunda metade usando a Biblioteca de Nuvem de Pontos. Não posso provar, mas me considero um especialista mais forte em PCL, tendo passado os três primeiros anos pensando em soluções que outros já forneciam.
Jan Hackenberg
@ JanHackenberg - sim, mas deixe-me também ser franco: você perdeu três anos de sua vida reinventando as rodas. Imagine quantas coisas novas você poderia ter feito se tivesse usado o que os outros fizeram !?
Wolfgang Bangerth
Decidi escrever em Java no meu primeiro ano de doutorado, porque naquele momento considerava minhas habilidades de programação (não a teoria em informática) próximas de zero. Java ainda era a linguagem que eu era melhor na prática. Também considerei o Java uma boa escolha por causa do fácil suporte a várias plataformas. Entrei em uma cadeira sem suporte informático no doutorado (silvicultura tradicional). Eu pulei para o c ++ quando percebi o meu erro e pude (depois da publicação, não antes).
Jan Hackenberg
BTW eu discordo em experimentar 3 anos da minha vida. Isso significaria que eu tinha apenas dois anos úteis na experiência de pós-doutorado. Hoje eu posso encaixar 10 bilhões de cilindros em uma nuvem de pontos florestais e deixar a máquina decidir quais são boas para representar as árvores. Meus ~ 50 usuários também podem fazê-lo. Em ~ 1 hora. Todos os truques que aprendi aprendendo da maneira mais difícil e demorada. Decidi nunca aprender a usar o vi, mas quando as pessoas que passam pela curva de aprendizado necessária afirmam usar a maneira mais eficiente de produzir código, eu acredito nelas.
Jan Hackenberg
2

O grupo com o qual trabalho utiliza bibliotecas o máximo possível. Sou um dos poucos programadores, e o resto das pessoas começou a programar no trabalho. Eles sabem o suficiente de suas próprias limitações para saber onde não devem se interessar. IMSL é a biblioteca preferida. Coisas como a GSL seriam proibidas devido a restrições de licenciamento, mesmo que essa seja uma agência federal e que entregemos nosso software de qualquer maneira.

Tangurena
fonte
2

"A reutilização é principalmente um fenômeno social. Eu posso usar o software de outra pessoa, desde que

  1. funciona
  2. é compreensível
  3. pode coexistir
  4. é suportado (ou estou disposto a apoiá-lo, principalmente não sou)
  5. é econômico
  6. Eu consigo encontrar.

"- Stroustrup, The C ++ Programming Language 2 ed. (1991) p. 383.


fonte
1

Várias boas razões foram apresentadas por outras pessoas para usar bibliotecas e também para rolar suas próprias rotinas.

Às vezes, você pode acelerar os cálculos para um aplicativo específico porque sabe com antecedência que nunca precisará da ampla gama de valores que a rotina da biblioteca cobre ou da precisão que essas rotinas fornecem.

Obviamente, depende muito do aplicativo específico e de quantas vezes a rotina da biblioteca será chamada. Por que você chamaria uma rotina de biblioteca de funções de Bessel bilhões de vezes se você só precisa de alguns números significativos para um pequeno intervalo de x, e alguma técnica mais simples será suficiente para suas necessidades?

Lysistrata
fonte
0

É pouco a acrescentar, temos que reutilizar o código, trata-se de sustentabilidade e contribuição do código para a sociedade, mas isso é tudo acima.

A razão pela qual não reutilizamos o código é que, se você está iniciando o programador, é difícil entender o código de outras pessoas. É particularmente difícil com o C ++ avançado, e você também pode fazer alguns truques em C puro.

Muitas vezes, no início, entendemos o método, mas não como ele é implementado na biblioteca, ou simplesmente como usar a biblioteca com sua interface genérica, controle de erros e convenções, muitas vezes documentadas para programadores experientes, se é que existem. Isso dá a ilusão de que é melhor implementar um método padrão, como a fatoração da LU sozinho. Além disso, novos programadores subestimam o valor do teste de código, validação e portabilidade para diferentes sistemas operacionais. Portanto, no final, a razão é a preguiça, escrever código próprio parece ser uma solução mais rápida e fácil.

A realidade é que podemos aprender mais usando e lendo código do que programando você mesmo do zero.

A preguiça me leva a maior parte do tempo, acho que também a maioria das pessoas. Pelo mesmo motivo, alguns escrevem código do zero e outros usam bibliotecas existentes.

likask
fonte
-1

Os algoritmos de bibliotecas fornecem, em contraste com as próprias implementações:

  • Eles são genéricos e modelados. Posteriormente, você pode remeter novamente sua implementação sem se preocupar em alterar seu próprio código, que deve ter muitas restrições.
  • Existem casos seguros e degenerados de dados de entrada. Muitos algoritmos de geometria computacional, por exemplo, os de casco convexo, precisam lidar com, por exemplo, colinearidade de três pontos. Você poderá ignorar esses casos se nunca planeja distribuir seu código e também não deseja reutilizá-lo no futuro com frequência.
  • Eles fornecem a complexidade mínima do tempo de execução para configurações de entrada esperadas ou na pior das hipóteses. Algoritmos de nível superior têm como tijolos de construção frequentemente algoritmos de nível inferior, por exemplo, algoritmos de classificação ou tipos de dados especiais. A classificação rápida pode ser a opção mais comum para classificar dados, mas se sua implementação do algoritmo precisar garantir n (log (n)), você não poderá usá-lo.
  • Eles são eficientes no uso da memória
  • Eles têm ainda mais tempo de execução otimizado
  • Se suportado, é muito mais fechado para estar livre de "bugs" em geral, especialmente se você trabalha com o ramo principal. Nada é mais testado do que uma biblioteca bem distribuída. Nem todo bug trava, nem todo bug produz resultados irracionais. A implementação do seu algoritmo ainda pode produzir resultados aceitáveis, apenas não tão bons quanto foram projetados. Quanto menos visível um bug, menor a probabilidade de você, como uma única pessoa, conseguir detectá-lo.

Ainda considero bom ao inserir um novo campo implementar uma versão de um algoritmo bem compreensível por conta própria. Eu levo muito tempo no total. Comprei e li livros, chamado Press et al. Eu sempre leio muita teoria antes e durante essas implementações. E depois de entender os conceitos gerais de um campo e experimentar as armadilhas na prática para mim, é hora de pular para as implementações de bibliotecas melhores em todos os aspectos. Eu acho que você se tornará um usuário melhor da biblioteca se você escrever um algoritmo "olá mundo" no campo de bibliotecas por conta própria.

Se você trabalha em uma equipe maior, pode não ser sua escolha se a sua equipe usa uma biblioteca específica ou não. A equipe principal pode tomar a decisão. E pode haver uma pessoa responsável pela ligação da biblioteca em seu projeto com seus próprios planejamentos de tempo. Reescrevendo um algoritmo que você pode fazer com seu próprio planejamento de tempo, sem depender da decisão de outras pessoas.

Se você está sozinho e gosta de distribuir, existe outro problema. Considero, assim como muitos outros códigos fonte, o recurso mais útil. Muitos de todos os informáticos podem concordar aqui. Em um campo aplicado fora da informática, pode ser necessário fornecer um executável pré-compilado no Windows. No Linux, você pode configurar as coisas de forma relativamente fácil por conta própria, no caso de bibliotecas de uso de código aberto.

Reescrever um algoritmo por conta própria oferece liberdade de permissão. Seu projeto pode não suportar a licença GPL da GSL, por exemplo.

A isenção pode ser a única restrição que é independente do ponto de vista dos pesquisadores.

Jan Hackenberg
fonte
11
É absurdo pensar que "implementar um algoritmo sozinho" e "aprender [a] sintaxe da biblioteca" custaria "ao mesmo tempo". Isso não é verdade para funções simples como "strcat". Definitivamente, não é o caso de qualquer coisa que esteja no LAPACK, por exemplo, ou em bibliotecas de nível superior.
Wolfgang Bangerth
@WolfgangBangerth Obrigado pelo feedback. Reli o que escrevi e não queria transferir a mensagem de que as próprias implementações podem ser executáveis. Mas eu aprendi muito. Meu "ambos podem custar duas semanas" não foi um bom exemplo. De fato, me custou a última vez que "aprendi a sintaxe" duas semanas quando mudei de Java para C ++ e também aprendi a sintaxe básica de C ++ nesse momento. Lutei mais com ponteiros do que com minha nova biblioteca. Duas semanas em qualquer um dos meus algoritmos implementados podem ter sido o tempo de codificação, que foi meu investimento menor (ler livros antes leva muito mais tempo).
Jan Hackenberg
O investimento não está na escrita de um pequeno algoritmo em si. Isso é rápido e, de fato, às vezes pode demorar até o aprendizado de outra biblioteca. O que custa incrivelmente muito tempo é depurar as coisas e acertar todos os casos de canto. Se você usar uma biblioteca bem desenvolvida, saberá que, se o produto vetor de matriz funcionar para matrizes quadradas, também funcionará para matrizes retangulares. Para o seu próprio software, você pode implementar e depurar isso, mesmo que tenha pensado que tinha terminado a função. Você voltará à mesma função várias vezes. Isso é o que custa tempo.
Wolfgang Bangerth
@WolfgangBangerth Concordo com todos os seus argumentos. Meu único argumento é que você aprende muito mais teoria quando precisa lidar com esses casos de canto. Minha primeira versão da minha resposta realmente parecia não fazer diferença. Eu estava horrivelmente cansado. Escrevo na resposta aprimorada muito mais sobre os benefícios de estabilidade das bibliotecas. Para mim, é uma troca entre o tempo gasto e o conhecimento adquirido.
Jan Hackenberg