O que bloqueia o Ruby, Python para obter a velocidade do Javascript V8? [fechadas]

261

Existem recursos Ruby / Python que estão bloqueando a implementação de otimizações (por exemplo, cache embutido ) que o mecanismo V8 possui?

O Python é co-desenvolvido pela equipe do Google, portanto não deve ser bloqueado pelas patentes de software.

Ou isso é uma questão de recursos colocados no projeto V8 pelo Google.

Greg Dan
fonte
6
A introspecção e a sobrecarga do operador provavelmente são grandes, mas eu não conheço JS o suficiente para lhe dar uma resposta real. O projeto PyPy é provavelmente a melhor chance do Python atingir o tipo de velocidade JS.
Ncoghlan #
11
Você tem algum exemplo em que o PyPy é mais lento que o V8, exceto o tiroteio na linguagem de computador, que é uma besteira completa (veja como as coisas são implementadas de maneira diferente em diferentes idiomas). Ou é apenas o campo de distorção da realidade do google?
fijal 3/03/11
3
V8 não é tão parecido com Python. Aguarde até a V8 ter que implementar a especificação 1.8 Javascript para fazer uma comparação melhor. E nesse ponto, tenho certeza de que alguém tentará implementar o PyPy no topo do mecanismo V8 no lugar do Javascript.
Michael Dillon
14
Por que você tem tanta certeza de que o V8 é mais rápido que o Python ou o Ruby? Em que?
jcoffland
6
V8 é absolutamente mais rápido que Python / Ruby. Faça qualquer tipo de benchmark desejado, desde o simples microbenchmark até um aplicativo abrangente do mundo real, escrito em idiomas nos dois ambientes. É uma ordem de magnitude mais rápida para a maioria das operações nativas da linguagem (ou seja, coisas que não são delegadas ao código C no Python).
Hejazzman

Respostas:

519

O que bloqueia o Ruby, Python para obter a velocidade do Javascript V8?

Nada.

Bem, tudo bem: dinheiro. (E tempo, pessoas, recursos, mas se você tiver dinheiro, poderá comprá-los.)

A V8 tem uma equipe de engenheiros brilhantes, altamente especializados, altamente experientes (e, portanto, muito bem pagos) trabalhando nele, que têm décadas de experiência (estou falando individualmente - coletivamente, são mais como séculos) na criação de execução de alto desempenho mecanismos para linguagens OO dinâmicas. Eles são basicamente as mesmas pessoas que também criaram a Sun HotSpot JVM (entre muitas outras).

Lars Bak, o desenvolvedor líder, trabalha literalmente em VMs há 25 anos (e todas essas VMs chegaram à V8), que é basicamente sua vida (profissional). Algumas das pessoas que escrevem VMs Ruby não têm nem 25 anos.

Existem recursos Ruby / Python que estão bloqueando a implementação de otimizações (por exemplo, cache embutido) que o mecanismo V8 possui?

Dado que pelo menos o IronRuby, o JRuby, o MagLev, o MacRuby e o Rubinius têm cache embutido monomórfico (IronRuby) ou polimórfico, a resposta é obviamente não.

As implementações modernas do Ruby já fazem muitas otimizações. Por exemplo, para certas operações, a Hashclasse de Rubinius é mais rápida que a de YARV. Agora, isso não parece muito empolgante até você perceber que a Hashclasse do Rubinius é implementada em 100% puro Ruby, enquanto o YARV é implementado em 100% otimizado para a mão C.

Portanto, pelo menos em alguns casos, Rubinius pode gerar um código melhor que o GCC!

Ou isso é uma questão de recursos colocados no projeto V8 pelo Google.

Sim. Não é só o Google. A linhagem do código fonte do V8 tem 25 anos. As pessoas que estão trabalhando na V8 também criaram a Self VM (até hoje um dos mais rápidos mecanismos dinâmicos de execução de linguagem OO já criados), a Animorphic Smalltalk VM (até hoje um dos mais rápidos mecanismos de execução Smalltalk já criados), o HotSpot JVM (a JVM mais rápida já criada, provavelmente o período de VM mais rápido) e OOVM (uma das VMs Smalltalk mais eficientes já criadas).

De fato, Lars Bak, o principal desenvolvedor do V8, trabalhou em cada um deles, além de alguns outros.

Jörg W Mittag
fonte
1
Podemos ter alguma literatura de referência sobre "Dado que pelo menos o IronRuby, o JRuby, o MagLev, o MacRuby e o Rubinius têm cache em linha monomórfico (IronRuby) ou polimórfico em linha, a resposta é obviamente não". por favor?
WDRust
14
SpiderMonkey tem desempenho comparável, então, como a Mozilla fez isso? Eles têm muito dinheiro limitado ..
Salman von Abbas
8
@SalmanPK: não é sua primeira VM, e também há pessoas inteligentes trabalhando na Mozilla.
Matthieu M.
3
@SalmanPK, miguel: A Mozilla criou sua JS VM pelo menos em parte pela engenharia reversa V8. blog.mozilla.org/dmandelin/2010/09/08/presenting-jagermonkey
Ian
2
O @Ian V8 é de código aberto (licença BSD), portanto não há necessidade de fazer engenharia reversa, basta ver o que eles estão fazendo.
dbkk
78

Há muito mais ímpeto para otimizar altamente os interpretadores JavaScript, e é por isso que vemos tantos recursos sendo colocados entre eles, Mozilla, Google e Microsoft. O JavaScript deve ser baixado, analisado, compilado e executado em tempo real enquanto um ser humano (geralmente impaciente) está esperando por ele, ele deve ser executado QUANDO uma pessoa estiver interagindo com ele, e estiver fazendo isso em um cliente não controlado ambiente que pode ser um computador, um telefone ou uma torradeira. Tem que ser eficiente para executar sob essas condições de forma eficaz.

Python e Ruby são executados em um ambiente controlado pelo desenvolvedor / implementador. Um servidor robusto ou sistema de desktop geralmente onde o fator limitante será coisas como E / S de memória ou disco e não tempo de execução. Ou onde otimizações que não são de mecanismo, como cache, podem ser utilizadas. Para esses idiomas, provavelmente faz mais sentido concentrar-se no conjunto de recursos de idioma e biblioteca que otimiza a velocidade.

O benefício colateral disso é que temos dois grandes mecanismos JavaScript de código aberto de alto desempenho que podem e estão sendo redirecionados para todos os tipos de aplicativos, como o Node.js.


fonte
43

Boa parte disso tem a ver com a comunidade. Python e Ruby geralmente não têm suporte corporativo. Ninguém é pago para trabalhar em Python e Ruby em tempo integral (e eles especialmente não são pagos para trabalhar em CPython ou MRI o tempo todo). O V8, por outro lado, é apoiado pela empresa de TI mais poderosa do mundo.

Além disso, o V8 pode ser mais rápido porque a única coisa que importa para o pessoal do V8 é o intérprete - eles não têm uma biblioteca padrão para trabalhar, nenhuma preocupação com o design da linguagem. Eles apenas escrevem o intérprete. É isso aí.

Não tem nada a ver com a lei de propriedade intelectual. O Python também não é co-desenvolvido pelos caras do Google (seu criador trabalha lá junto com alguns outros committers, mas eles não são pagos para trabalhar no Python).

Outro obstáculo à velocidade do Python é o Python 3. Sua adoção parece ser a principal preocupação dos desenvolvedores de linguagem - a ponto de congelar o desenvolvimento de novos recursos de linguagem até que outras implementações se atualizem.

Quanto aos detalhes técnicos, não sei muito sobre Ruby, mas o Python tem vários locais onde otimizações podem ser usadas (e o Unladen Swallow, um projeto do Google, começou a implementá-las antes de morder a poeira). Aqui estão algumas das otimizações que eles planejaram . Eu poderia ver o Python ganhando velocidade V8 no futuro se um JIT à la PyPy for implementado para o CPython, mas isso não parece provável nos próximos anos (o foco agora é a adoção do Python 3, não um JIT).

Muitos também acham que Ruby e Python poderiam se beneficiar imensamente da remoção de seus respectivos bloqueios globais de intérpretes .

Você também precisa entender que Python e Ruby são linguagens muito mais pesadas que JS - elas fornecem muito mais na biblioteca padrão, recursos de linguagem e estrutura. Só o sistema de classes de orientação a objetos acrescenta muito peso (no bom sentido, eu acho). Eu quase penso no Javascript como uma linguagem projetada para ser incorporada, como Lua (e de várias maneiras, elas são semelhantes). Ruby e Python têm um conjunto muito mais rico de recursos, e essa expressividade geralmente custa à velocidade.

Rafe Kettler
fonte
3
Na verdade, a moratória sobre novos recursos foi levantada desde o recente lançamento do Python 3.2.
jd.
2
+1, mas um congelamento em novos recursos de idioma significaria mais tempo para gastar em otimização?
Andrew Grimm
1
@ Andrew se apenas. O foco está em trazer Jython, IronPython e PyPy até a velocidade, à espera de bibliotecas para converter em Python 3, e evangelizadora Python 3.
Rafe Kettler
2
"O sistema de classes de orientação a objetos, por si só, acrescenta muito peso" - VMs JavaScript modernas, como a V8, têm classes, são apenas implícitas. Assim como no Python, você não precisa digitar explicitamente uma variável em JavaScript, não precisa digitar explicitamente uma classe. A VM é inteligente o suficiente para analisar seu código e extrair classes.
Benjamin Gruenbaum
1
Pelo que entendi, o V8 é um compilador JIT em vez de um intérprete ... Tenho certeza de que há uma distinção entre os dois. Talvez não ... eu não sei.
24413 Luke
24

O desempenho não parece ser o foco principal dos principais desenvolvedores de Python, que parecem sentir que "rápido o suficiente" é bom o suficiente e que os recursos que ajudam os programadores a serem mais produtivos são mais importantes do que os recursos que ajudam os computadores a executar o código mais rapidamente.

De fato, no entanto, havia um projeto do Google (agora abandonado), sem carga , para produzir um interpretador Python mais rápido, compatível com o intérprete padrão. PyPy é outro projeto que pretende produzir um Python mais rápido. Há também Psyco , o precursor do PyPy, que pode fornecer aprimoramentos de desempenho para muitos scripts Python sem alterar todo o intérprete, e Cython , que permite escrever bibliotecas C de alto desempenho para Python usando algo muito parecido com a sintaxe do Python.

kindall
fonte
13

Pergunta enganosa. A V8 é uma implementação JIT (um compilador just-in-time) de JavaScript e, em sua implementação mais popular do Node.js, sem navegador, é construída em torno de um loop de eventos. CPython não é um JIT e não está registrado. Mas eles existem no Python mais comumente no projeto PyPy - um JIT compatível com o CPython 2.7 (e em breve será 3.0+). E há muitas bibliotecas de servidores com eventos como o Tornado, por exemplo. Existem testes no mundo real entre o PyPy executando Tornado vs Node.js e as diferenças de desempenho são pequenas.

Handloomweaver
fonte
3
+1 por mencionar Tornado . Embora atinja uma velocidade comparável à do Node.js, seu gen.enginemódulo junto aos geradores Python e a yieldinstrução ( desde a versão 2.5 !!! podem redefinir sua codificação assíncrona.
Lukas Bünger
1
Desde a sua publicação, o pypy lançou uma versão estável suportada 3.x (e continua melhorando o suporte, é claro): morepypy.blogspot.fr/2014/06/pypy3-231-fulcrum.html
Zeograd
9

Acabei de me deparar com essa pergunta e também há uma grande razão técnica para a diferença de desempenho que não foi mencionada. O Python possui um ecossistema muito grande de poderosas extensões de software, mas a maioria dessas extensões é escrita em C ou em outras linguagens de baixo nível para desempenho e está fortemente ligada à API do CPython.

Existem muitas técnicas conhecidas (JIT, coletor de lixo moderno etc.) que podem ser usadas para acelerar a implementação do CPython, mas todas exigiriam alterações substanciais na API, quebrando a maioria das extensões do processo. O CPython seria mais rápido, mas muito do que torna o Python tão atraente (a extensa pilha de softwares) seria perdido. Caso em questão, existem várias implementações mais rápidas do Python por aí, mas elas têm pouca tração em comparação com o CPython.

Jason McCampbell
fonte
9

Devido a diferentes prioridades de design e objetivos de caso de uso, acredito.

Em geral, o principal objetivo das linguagens de script (também conhecidas como dinâmicas) é ser uma "cola" entre chamadas de funções nativas. E essas funções nativas devem: a) cobrir as áreas mais críticas / usadas com frequência; eb) ser o mais eficaz possível.

Aqui está um exemplo: Classificação do jQuery fazendo o iOS Safari congelar O congelamento é causado pelo uso excessivo de chamadas get-by-selector. Se o get-by-selector fosse implementado no código nativo e, efetivamente, não haverá esse problema.

Considere a demonstração do ray-tracer que é frequentemente usada na demonstração da V8. No mundo Python, ele pode ser implementado em código nativo, pois o Python fornece todos os recursos para extensões nativas. Mas no domínio V8 (sandbox do lado do cliente), você não tem outras opções além de tornar a VM o mais eficiente possível. E assim, a única opção que existe é a implementação do ray-tracer, usando o código de script.

Tão diferentes prioridades e motivações.

No Sciter , fiz um teste implementando praticamente o núcleo completo do jQurey de forma nativa. Em tarefas práticas como ScIDE (IDE feito de HTML / CSS / Script), acredito que essa solução funcione significativamente melhor do que qualquer otimização de VM.

sorriso
fonte
5

Como outras pessoas mencionaram, o Python possui um compilador JIT de desempenho na forma de PyPy .

Fazer benchmarks significativos é sempre sutil, mas, por acaso, tenho um benchmark simples de meios K escrito em diferentes idiomas - você pode encontrá-lo aqui . Uma das restrições era que as várias linguagens deveriam implementar o mesmo algoritmo e deveriam se esforçar para serem simples e idiomáticas (em vez de otimizadas para velocidade). Eu escrevi todas as implementações, então sei que não trapaceie, embora não possa reivindicar para todas as línguas que o que escrevi é idiomático (só tenho um conhecimento passageiro de algumas delas).

Não reivindico nenhuma conclusão definitiva, mas o PyPy foi uma das implementações mais rápidas que obtive, muito melhor que o Node. O CPython estava no final mais lento do ranking.

Andrea
fonte
5

A afirmação não é exatamente verdadeira

Assim como a V8 é apenas uma implementação para JS, o CPython é apenas uma implementação para Python. Pypy tem performances correspondentes aos V8 .

Além disso, existe o problema do desempenho percebido: como a V8 é nativa e sem bloqueio, o desenvolvedor da Web leva a projetos com melhor desempenho porque você salva a espera de E / S. E o V8 é usado principalmente para a Web dev, onde a IO é essencial, então eles a comparam a projetos semelhantes. Mas você pode usar o Python em muitas outras áreas além do web dev. E você pode até usar extensões C para várias tarefas, como cálculos ou criptografia científica, e processar dados com excelentes resultados.

Mas na web, os projetos mais populares de Python e Ruby estão bloqueando. O Python, especialmente, tem o legado do padrão WSGI síncrono, e estruturas como o famoso Django são baseadas nele.

Você pode escrever Python assíncrono (como Twisted, Tornado, gevent ou asyncio) ou Ruby. Mas isso não é feito com frequência. As melhores ferramentas ainda estão bloqueando.

No entanto, são algumas das razões pelas quais as implementações padrão no Ruby e Python não são tão rápidas quanto a V8.

Experiência

Como Jörg W Mittag apontou, os caras que trabalham no V8 são gênios da VM. Python é um desenvolvedor de pessoas apaixonadas, muito bom em muitos domínios, mas não é tão especializado em ajustes de VM.

Recursos

A fundação Python Software tem muito pouco dinheiro: menos de 40 mil em um ano para investir em Python. Isso é meio louco quando você pensa que grandes jogadores como Google, Facebook ou Apple estão usando Python, mas é a verdade feia: a maioria do trabalho é feita de graça. A linguagem que alimenta o YouTube e existia antes do Java foi criada por voluntários.

Eles são voluntários inteligentes e dedicados, mas quando identificam que precisam de mais suco em um campo, não podem pedir 300 mil para contratar um especialista de primeira linha para essa área de especialização. Eles precisam procurar alguém que faça isso de graça.

Enquanto isso funciona, significa que você deve ter muito cuidado com suas prioridades. Portanto, agora precisamos olhar para:

Objetivos

Mesmo com os recursos modernos mais recentes, escrever Javascript é terrível. Você tem problemas de escopo, pouquíssimas coleções, manipulação terrível de cadeias de caracteres e matrizes, quase nenhuma lista padrão, exceto data, matemática e expressões regulares, e nenhum açúcar sintático nem para operações muito comuns.

Mas na V8, você tem velocidade.

Isso porque a velocidade era o principal objetivo do Google, pois é um gargalo para a renderização da página no Chrome.

No Python, a usabilidade é o objetivo principal. Porque quase nunca é o gargalo do projeto. O recurso escasso aqui é o tempo do desenvolvedor. É otimizado para o desenvolvedor.

e-satis
fonte
1

Como as implementações de JavaScript não precisam se preocupar com a compatibilidade com versões anteriores de suas ligações.

Até recentemente, os únicos usuários das implementações de JavaScript eram navegadores da web. Devido a requisitos de segurança, apenas os fornecedores do navegador da Web tiveram o privilégio de estender a funcionalidade gravando ligações nos tempos de execução. Portanto, não havia necessidade de manter a API C das ligações compatível com versões anteriores; era permitido solicitar que os desenvolvedores do navegador da Web atualizassem seu código-fonte à medida que os tempos de execução do JavaScript evoluíssem; eles estavam trabalhando juntos de qualquer maneira. Até o V8, que chegou atrasado ao jogo e também liderado por um desenvolvedor muito experiente, mudou a API à medida que se tornou melhor.

OTOH Ruby é usado (principalmente) no lado do servidor. Muitas extensões ruby ​​populares são gravadas como ligações C (considere um driver RDBMS). Em outras palavras, Ruby nunca teria conseguido sem manter a compatibilidade.

Hoje, a diferença ainda existe até certo ponto. Os desenvolvedores que usam o node.js estão reclamando que é difícil manter suas extensões nativas compatíveis com versões anteriores, pois a V8 altera a API ao longo do tempo (e esse é um dos motivos pelos quais o node.js foi bifurcado). O rubi do IIRC ainda está adotando uma abordagem muito mais conservadora a esse respeito.

kazuho
fonte
1

O V8 é rápido devido ao JIT, eixo de manivela, o tipo de inferenciador e o código otimizado para dados. Ponteiros marcados, NaN-marcação de duplas. E é claro que ele faz otimizações normais do compilador no meio.

Os mecanismos simples de ruby, python e perl não fazem nenhum desses, apenas pequenas otimizações básicas.

A única grande vm que chega perto é o luajit, que nem faz inferência de tipo, dobragem constante, marcação NaN nem números inteiros, mas usa estruturas pequenas de código e dados semelhantes, não tão gordas quanto as linguagens ruins. E minhas linguagens dinâmicas de protótipo, poção e p2 têm recursos semelhantes ao luajit e superam a v8. Com um sistema de tipo opcional, "digitação gradual", você pode facilmente superar a v8, pois pode ignorar o eixo de manivela. Veja dardo.

Os backends otimizados conhecidos, como pypy ou jruby, ainda sofrem com várias técnicas de engenharia excessiva.

suburbano
fonte
Veja também github.com/rahul080327/medusa
Günter Zöchbauer