Quão rápido o Go pode ir?

39

Go é uma das poucas linguagens que devem rodar 'perto do metal', ou seja, é compilada, com estaticamente digitado e executa código nativamente, sem uma VM. Isso deve proporcionar uma vantagem de velocidade em relação a Java, C # e similares. Parece, no entanto, que está por trás do Java (consulte o tiroteio na linguagem de programação )

Estou assumindo que os compiladores menos maduros são extremamente responsáveis ​​por isso, mas existem outras razões? Existe algo inerente ao design do Go que o impeça de ser executado mais rapidamente do que o Java, por exemplo? Eu tenho uma visão muito pouco sofisticada dos modelos de tempo de execução, mas parece que pelo menos em princípio ele deve ser capaz de executar mais rápido que o Java, graças à execução de código nativo.

Greg Slodkowicz
fonte
3
Dado um compilador suficientemente inteligente (e / ou VM e / ou compilador JIT), um determinado idioma sempre pode ir mais rápido (bem, existem limitações físicas, mas é isso). Obviamente, esse truísmo não ajuda ninguém, desde que este compilador suficientemente inteligente não esteja lá. Observe que o Java já possui implementações suficientemente inteligentes e é incrivelmente inteligente. Outro fato importante é que a execução do código tem pelo menos tanta influência no desempenho do tempo de execução quanto a implementação.
1
Entendo isso, mas fiquei pensando se é razoável esperar que a velocidade do Go corresponda / supere, por exemplo, Java, à medida que o compilador amadurece.
Greg Slodkowicz
17
Linguagens de programação não têm velocidade. Nem implementações de linguagem. Uma implementação de um determinado idioma possui uma velocidade para algumas entradas, e essa velocidade pode variar muito dependendo da entrada.
8
Me acorde .. antes que você vá ... WHAM! . Desculpe, eu não pude resistir. Aqui estão as bandeiras .. aqui estão as bandeiras ..
Tim Post
2
@delnan - Ou é muito mais fácil dizer "Java" do que dizer "Java (TM) SE Runtime Environment (compilação 1.6.0_25-b06) VM do servidor Java HotSpot (TM) de 64 bits (compilação 20.0-b11 , modo misto) ":-)
igouy 15/06

Respostas:

46

Em termos de design de linguagem, não há realmente nada que deva tornar o Go mais lento que o Java em geral. De fato, ele oferece mais controle do layout da memória de suas estruturas de dados; portanto, para muitas tarefas comuns, deve ser um pouco mais rápido. No entanto, o compilador primário Go atual, o planejador, o coletor de lixo, a biblioteca regexp e muitas outras coisas não são particularmente otimizados. Isso está melhorando constantemente, mas o foco parece ser útil, simples e rápido o suficiente para vencer as marcas de micropigmentação.

No benchmark vinculado, o Go perde muito para Java na árvore binária e no teste regexp. Esses são testes do sistema de gerenciamento de memória e da biblioteca regexp, respectivamente. O gerenciamento de memória da Go pode ser mais rápido e certamente melhorará com o tempo, e a atual biblioteca regexp padrão é um espaço reservado para uma implementação muito melhor que está por vir. Portanto, perder para os dois não é surpreendente, e em um futuro próximo a margem deve ser mais estreita.

Para o benchmark k-nucleotide, é um pouco difícil comparar, porque o código Java parece estar usando um algoritmo diferente. O código Go certamente se beneficiará das melhorias do compilador, agendador e alocador, mesmo que escritas, mas alguém teria que reescrever o código Go para fazer algo mais inteligente se quiséssemos comparar com mais precisão.

O Java vence no benchmark mandelbrot porque é tudo aritmético e loops de ponto flutuante, e este é um ótimo lugar para a JVM gerar código de máquina realmente bom e elevar coisas em tempo de execução. O Go, em comparação, possui um compilador bastante simples que não eleva, desenrola ou gera código de máquina realmente rígido atualmente, portanto, não é de surpreender que perca. No entanto, deve-se ter em mente que o tempo do Java não conta o tempo de inicialização da JVM ou as várias vezes em que ele precisa ser executado para que a JVM o faça corretamente. Para programas de longa duração, isso não é relevante, mas é importante em alguns casos.

Quanto ao restante dos benchmarks, Java e Go são basicamente de pescoço para pescoço, com Go consumindo significativamente menos memória e, na maioria dos casos, menos código. Portanto, embora o Go seja mais lento que o Java em vários desses testes, o Java é muito rápido, o Go se sai muito bem em comparação e o Go provavelmente ficará notavelmente mais rápido no futuro próximo.

Estou ansioso para quando o gccgo (um compilador Go que usa o código gcc) está maduro; isso deve deixar o Go praticamente alinhado com C para muitos tipos de código, o que será interessante.

Kyle C
fonte
2
Muito bem, entendendo que é sempre necessário olhar o código-fonte e verificar o que está sendo feito!
igouy
1
Em Java tempo de arranque para esses programas, consulte shootout.alioth.debian.org/help.php#java
igouy
2
Esse é exatamente o tipo de resposta que eu esperava, obrigado!
Greg Slodkowicz
Muito menos uso de código e memória, compila para código de máquina, melhor projetado. Tudo isso assume a desvantagem da velocidade.
Moshe Revah
22
  1. Sem nem dizer quais problemas foram resolvidos, todo o benchmark é inútil.
  2. JVM e CLR usam JITs para produzir código de máquina. Não há razão para que isso deva ser mais lento. Custa apenas idades para iniciar.
  3. O Go foi projetado para criar rapidamente . Você não tem toneladas de tempo de compilação e otimizações de tempo de inicialização. O Go compila sua própria biblioteca padrão quando um aplicativo Java é inicializado.

O Go poderia ser mais rápido em tempo de execução? Sim. O Go será mais rápido em tempo de execução? Eu não sei. Talvez os construtores do compilador adicionem otimização opcional ao custo do tempo de compilação. Mas não acho que eles tenham muito interesse nisso. Eles trabalham no Google.
O que eles querem é uma linguagem que permita um desenvolvimento rápido e que tenha um bom desempenho no que faz. Inferno, mesmo que essa referência fosse credível, isso significaria que eles eram metade da velocidade de C e 14 vezes a velocidade de Python. Isso é mais do que bom o suficiente.
O hardware é barato, o código é caro. O código tende a se tornar maior e mais lento à medida que você investe dinheiro, o hardware se torna mais barato e menor. Você quer uma linguagem que não exija 4 frameworks e 2000 classes para realizar qualquer coisa útil.
Não há nada inerente ao design do Go, que o torna lento. No entanto, há algo inerente aos designers de Go, que o torna mais lento que a montagem: senso comum.

back2dos
fonte
1
A maioria dos JITs (todos?) É compilada durante o tempo de execução, não quando o código é carregado pela primeira vez. Esse código de máquina pode não ser gerado para algum código e também pode ser facilmente invalidado, por exemplo, se o objsin for (obj : objs) { obj.meth() }tiver implementações diferentes de methcada vez e o JIT tentar incorporá-lo. Obviamente, tudo isso é realmente um benefício nos casos comuns, mas ainda é digno de nota.
@ delnan: O V8 JITs qualquer código antes de executá-lo. Além disso, o LLVM foi construído com o JITting em mente, portanto (com algum esforço, é claro), você pode fazer qualquer otimização a tempo, o que aconteceria em tempo de compilação. No entanto, certas otimizações, como a análise de escape, realmente funcionam apenas com JITs.
back2dos
3
>> Sem nem dizer quais problemas foram resolvidos << Veja e você verá que essas páginas da Web dizem quais problemas foram resolvidos. Na verdade, você vai encontrar o código fonte do programa, comandos construir, comandos de partida, versão implementação da linguagem, ya da ya da ya
igouy
10

Também notei que o Go foi particularmente lento no benchmark regex-dna . Russ Cox explicou por que a Go não teve esse desempenho nesse benchmark específico . A razão é que o pacote regexp da Go está usando um algoritmo de correspondência diferente que apresenta um desempenho ruim nesse benchmark específico, mas pode ser por magnitudes mais rápidas em outros benchmarks. Além disso, Ruby, Python e outras linguagens de script estão usando uma implementação C de outro algoritmo de correspondência regexp .

Finalmente, o jogo de benchmarks de linguagem de computador consiste em micro-benchmarks que podem não refletir com precisão muitas características das linguagens medidas e até mediar impressões erradas. Este trabalho de pesquisa, publicado recentemente pelo Google, oferece uma visão mais precisa de várias características da linguagem Go, Scala, Java e C ++ - particularmente a parte "V. Performance Analysis". Portanto, no final, Go é quase tão sedento de memória quanto Java (81% da memória de Java) e consome até 170% mais memória que Scala (não foi possível encontrar no artigo se o consumo de memória da JVM era considerado).

Mas, novamente, Go é jovem e ainda está em desenvolvimento pesado (alterações de API)! Muitas melhorias estão chegando em breve.

Alex
fonte
3
>> Este trabalho de pesquisa, publicado recentemente pelo Google << Não é um trabalho de pesquisa e não foi publicado pelo Google. É um relatório de experiência de um funcionário do Google apresentado no workshop Scala "Scala Days 2011".
Igouy 15/06/11
>> pode não refletir com precisão muitas características das linguagens medidas e até mediar impressões erradas. << Isso é verdade também para os programas de "reconhecimento de loop" e provavelmente para todas as comparações de desempenho entre diferentes linguagens de programação. Na verdade, o autor diz que - "Nós não explorar qualquer aspecto de multi-threading, ou mecanismos do género nível superior ... nós também não executam computação numérica pesado ..."
igouy
@igouy Na capa, você pode ler "Google" e tudo o que é relevante é coberto com as referências correspondentes. Então, por que não é um "trabalho de pesquisa publicado pelo Google" se o Google é mencionado com o endereço da sua sede? Os trabalhos de pesquisa não são um domínio exclusivo da academia.
21611 Alex
Na capa, você pode ler o endereço para correspondência em que o autor pode ser contatado e o endereço de e-mail do autor. Verifique o URL do pdf que você postou. Observe o domínio - days2011.scala-lang.org - o Scala Days 2011 "workshop Scala."
igouy
1

O Go é mais rápido que o Python e um pouco mais lento que o Java. Minha experiência aproximada constatou que o Go é muito (1-2 ordens de magnitude) mais rápido que o Python e cerca de 10 a 20% mais lento que o Java. No entanto, o Go é um pouco mais rápido que o Java, se usado com quad-core (x64). Go também é muito mais eficiente em termos de memória RAM.

Gostaria de acrescentar alguns pontos sobre o potencial de desempenho do Go contra Java e Python. O Go permite mais coisas que C faz, o que constantemente permite que C supere a maioria dos outros idiomas. As falhas de cache são muito importantes para evitar o código de alto desempenho. Reduzir as falhas de cache requer o controle do layout da memória de suas estruturas de dados. Go permite que você faça isso. Java não, o que torna mais difícil evitar a fragmentação da memória e do cache.

No momento, o Java geralmente roda mais rápido que o Go, porque o coletor de lixo do Java é muito mais sofisticado. Embora não haja razão, o coletor de lixo Go não poderia ser muito melhor. A geração de código também é provavelmente muito melhor para Java no momento. O Go tem muito potencial para melhorar, por exemplo, com suporte para instruções de vetores etc.

Então eu acho que é realmente apenas uma questão de tempo até o Go ultrapassar o Java. Embora, como em qualquer código de idioma, provavelmente não seja mais rápido automaticamente, ele será escrito no Go. Você precisa utilizar as facilidades que o idioma lhe oferece. Eu diria que o Go simplesmente oferece mais oportunidades para ajustar seu código.

Enfim, essa é apenas a experiência de um desenvolvedor.

Milo Banks
fonte
4
Esta é uma pergunta de 8 anos e o poder da computação barata tornou praticamente irrelevante. Sua resposta também é baseada no "seu sentimento" e não em dados concretos. Não quero desencorajá-lo, mas ...
Kayaman 28/06