Em 2018, pratiquei o Advento do Código (você pode assistir os fluxos de minhas soluções aqui ). Todos os dias em dezembro, eles postam um pequeno problema e você tem que escrever um programa que o resolva. Geralmente leva de alguns minutos a algumas horas e é muito divertido, recomendo que você experimente. Quando uma tarefa é concluída, ela está sempre disponível, não apenas em dezembro.
Percebi que existem dois tipos de soluções: aquelas que podem calcular a resposta em alguns milissegundos e aquelas que levarão a resposta por vários anos. Se você escolher a segunda opção, está fazendo algo errado. Não adianta esperar, embora, tecnicamente, isso também possa ser correto.
Outra observação interessante é que não importa qual hardware você usa para iniciar. Se a solução for rápida, será rápida tanto no laptop quanto na estação de trabalho com bomba. Claro, pode ser duas ou três vezes mais lento, mas a diferença será entre 10ms e 30ms. Você receberá sua resposta de qualquer maneira, então isso realmente não importa.
Por outro lado, se a solução for lenta, você pode usar qualquer poder de processamento e ainda não será suficiente. Isso poderia reduzir o tempo de execução de três anos (em um laptop) para um ano (no computador mais poderoso que posso construir). Qual é a diferença? De qualquer maneira, é muito longo.
Agora vamos passar para o software. É fácil chamar as soluções Advent Of Code de erradas quando são lentas, pois sabemos que deve existir uma solução rápida. Com problemas reais, ninguém garante.
Exceto em alguns casos.
Muitas vezes, na verdade.
Na verdade, eu diria quase sempre.
Vamos ver. Eu tenho uma biblioteca chamada Datascript . É uma estrutura de dados / base de dados persistente e acontece que está implementada para duas plataformas: JS e JVM. Além disso, na verdade ele é escrito em Clojure e a maior parte de sua base de código é usada por ambas as plataformas. Isso significa que sabemos que ambas as versões sempre fazem a mesma coisa. Há uma pequena camada que cobre detalhes específicos da plataforma, como tipos de dados e a biblioteca padrão, mas o resto é genérico. Não é que uma versão seja a original e a outra seja uma porta ineficiente. Ambos jogam o mesmo jogo.
Você pode estar pensando que se eles se comportarem da mesma forma, seu desempenho deve ser o mesmo, certo? Seria lógico pensar assim.
Vamos dar uma olhada no tempo real que leva para compilar a base de código e executar o conjunto completo de testes de integração. Estamos falando de uma base de código que tem pouco mais de 9.000 LOCs, dos quais 4.000 são testes:
Clojure 1.10 na JVM:
- Tempo de inicialização REPL: 1,5 seg
- Tempo de compilação: 6,5 s
- Tempo de testes: 0,45 seg
ClojureScript 1.10.439 com compilação avançada:
- Tempo de compilação: 78 s
- Tempo de testes: 1 seg
ClojureScript 1.10.439 sem compilação do Google Closure:
- Tempo de compilação: 24 s
- Tempo de testes: 1,3 s
Então, o que esses números nos dizem? Basicamente, você pode levar cerca de 8 segundos, 24 segundos ou 78 segundos para processar o mesmo código. A escolha é sua. Além disso, executando o mesmo programa, você pode obter o resultado em meio segundo, um segundo ou quase um segundo e meio.
“Mas espere, Tonsky, eles não podem ser comparados! Essas são duas grandes diferenças! Eles são projetados para fazer coisas completamente diferentes! Um deles funciona em um navegador! "
É claro que você pode obter resultados. Deixe-me lembrá-lo de que estamos compilando o mesmo código, construído para fazer a mesma coisa, usando os mesmos algoritmos e rodando no mesmo hardware. O resultado final é o mesmo em ambos os casos: você obtém uma resposta à sua consulta no registro de dados em pouco ou muito tempo. Ou você passa metade do dia esperando pelo compilador ou o passa jogando o REPL, construindo algo.
O que os compiladores ClojureScript / Google Closure vêm fazendo há tanto tempo? Eles estão perdendo seu tempo, é isso. Claro, ninguém é o culpado, mas no final, toda a decisão está simplesmente errada. Podemos fazer a mesma coisa muito mais rápido, temos evidências, temos os meios para fazer isso, mas acontece que não é. Mas poderíamos. Se você quisesse. Essa enorme sobrecarga que você paga, você paga em vão. Você não ganha nada com JS além de dobrar o tempo de execução e tempos de construção astronômicos.
O mesmo é verdadeiro para todas as linguagens com tempos de construção extremamente longos. Não é que eles não pudessem ser mais rápidos. Eles simplesmente optam por não fazê-lo. Um programa C ++ ou Rust demora muito para compilar? Bem, OCaml provavelmente poderia compilar um programa equivalente em menos de um segundo. E ainda será rápido no nível do carro.
“Uau, uau, devagar! Isso é ainda mais injusto! Agora não são apenas duas grandes diferenças, agora são como escovas de dente e naves espaciais. Você ignora completamente o que cada idioma oferece. Há um motivo pelo qual eles gastam tanto tempo compilando, sabe? "
Eu sei. Mesmo assim, acho que você pode compará-los. Afinal, são linguagens de uso geral e, no final das contas, o que importa é se você tem um programa de trabalho disponível e pode fornecer uma resposta em um prazo razoável. Não importa como o desenvolvedor chegou lá. Você pode se acalmar pensando que sim, mas ninguém liga para isso.
Imagine: um avião voa de Moscou a Novosibirsk, o coração da Sibéria, que percorre 2.800 quilômetros em 4 horas. Também há um trem que faz a mesma distância em três dias. Não há chuveiro no trem, comida ruim, camas nas quais você não consegue dormir. E um avião é um avião moderno confortável. Qual você escolheria? O mesmo preço. A única diferença é seu conforto e seu tempo.
Se tomarmos isso como uma metáfora de desenvolvimento de software, você ficará surpreso se os programadores pegarem o trem feliz. Eles até argumentam a ponto de ficarem roucos que há razões irrefutáveis para escolher um trem. Não, eles não se importam se o compilador demorar para "trabalhar". No entanto, existem maneiras mais rápidas de chegar ao mesmo destino. É fácil ficar confuso ao discutir detalhes, mas lembre-se: todos nós acabamos no mesmo lugar , não importa o idioma que falemos.
Navegadores? A mesma história. HTML é uma forma bastante ineficiente de posicionar pixels na tela. Um computador que pode exibir milhões de polígonos em um quadro pode ter dificuldade para carregar uma página da web. Tal como acontece com as soluções Advent of Code, isso não depende da potência do seu computador. E mesmo o código da web altamente otimizado baseado em Canvas e WebAssembly ( Figma ) mantém meus fãs do Macbook girando em completo silêncio quando eu lanço meu próprio Sketch.
- * tapinhas na capa * Este PC é capaz de rodar Crysis 3 em 4K a 144fps.
- Mas ele pode rodar o Atom?
Existem simplesmente limites para o quão longe essa decisão errada pode ir. Os editores de texto no Electron não podem redimensionar a janela em tempo real e cair em quadros quando você simplesmente move o cursor. O Slack no iMac Pro será tão lento e consome muita memória quanto em um Macbook de 12 polegadas.
Toda a decisão, a "pilha da web", geralmente está errada . O mesmo poderia ser feito de forma mais rápida e eficiente - há muito potencial desperdiçado. É hora de admitir e começar de novo. Existem editores de texto rápidos e programas de comunicação que estão disponíveis até mesmo para os netbooks mais fracos.
Posso continuar por muito tempo. Lembre-se do seguinte: pense no que você ganha com isso. O problema e os recursos gastos nele são comparáveis? É fácil encontrar desculpas para explicar por que as coisas são como são. Provavelmente são todos válidos, mas são desculpas. Sabemos que programas mais rápidos são possíveis e isso faz com que todo o resto dê errado.