Como o tipo é verificado em um interpretador / compilador de idioma dinâmico, como JavaScript?

11

Em linguagens dinâmicas, como JavaScript ou Python, o tipo de variável é determinado em tempo de execução. Essa é uma das razões pelas quais elas são mais lentas do que as linguagens digitadas, como Java.

Como é realizada a verificação de tipo? Qual é a razão essencial desse processo ser lento?


fonte
Eles não são mais lentos porque são dinâmicos, são mais lentos porque é mais difícil torná-los mais rápidos. JavaScript é realmente o mais otimizado e é bastante rápido.
Derek Litz

Respostas:

5

Há confusão na pergunta.

Supõe-se que a verificação de tipo seja lenta, o que não é necessariamente o caso.

A questão também parece confundir o processo de despacho de tipo com a verificação de tipo , e são duas coisas diferentes. Um é um processo feito em tempo de execução, o outro é um processo em tempo de compilação. Eu suspeito que a pergunta está realmente perguntando sobre o envio de tipo.

É o despacho de tipo que pode introduzir sobrecarga no tempo de execução, porque a computação gasta tempo com instruções que decidem dinamicamente qual ação executar, com base nos tipos de valores que vê no tempo de execução. por exemplo, em um idioma dinâmico, se eu aplicar "+" em duas coisas, pode significar adição numérica ou concatenação de strings; portanto, preciso dedicar algum tempo a analisar o que está à mão para decidir o que fazer. Existem estratégias de avaliação que podem reduzir o custo do envio dinâmico. (por exemplo, rastreando JITs)

Com relação à verificação de tipo em JavaScript, consulte: http://www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-flow-typing-theory/ . Para uma visão geral mais geral de como os verificadores de tipos funcionam, um manual de linguagem de programação padrão abordará os algoritmos. Por exemplo, http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/

dyoo
fonte
Também escrevi uma pequena pesquisa sobre rastreamento de JITs e idiomas dinâmicos em hashcollision.org/comprehensive/tracing.pdf
O interpretador Javascript carrega bits de tag com cada valor para envio de tipo. Você poderia elaborar um pouco sobre isso? Por exemplo, para que servem os bits de tag? Um pouco corresponde a um tipo?
O conceito de um tipo nem sempre está conectado à representação. Podemos ter um conceito de tipo 'milha' vs um tipo 'quilômetro', por exemplo, e é razoável ter uma linguagem que possa detectar estaticamente, em tempo de compilação, se os cálculos estão aplicando incorretamente operações em valores que atrapalham os tipos . Você pode imaginar que eles teriam a mesma representação e, se o compilador puder, em tempo de compilação, garantir que nunca seja misturado, não há razão para que os valores precisem de rotulagem adicional na representação.
1
Continuando: mas frequentemente, especialmente em idiomas dinâmicos, você deseja representar valores de diferentes tipos. Existem várias maneiras de fazer essa discriminação. Tags de tipo são comuns, mas existem outras técnicas. Por exemplo, você pode colocar certos tipos em regiões bloqueadas da memória. Consulte "Representando informações de tipo em idiomas de tipo dinâmico". lambda-the-ultimate.org/node/3912 para uma pesquisa abrangente das técnicas de representação.
7

Muito basicamente, em linguagens sem tipo, toda referência aponta para um objeto que contém o tipo e o valor. Por exemplo, var a = 3aponta para uma instância que contém o valor 3 e o tipo int, se você criar a = "bla", a referência é atualizada para uma instância que contém a string "bla" e a string de tipo, o objeto antigo é descartado, etc.

Isso é lento porque toda vez que uma operação (por exemplo a + b) deve ser feita nesse tipo básico, o tempo de execução deve primeiro desreferenciar os objetos, verificar se seu tipo é compatível, executar a operação, criar um novo objeto.

Por outro lado, a + bem C ++ ou Java verifica, em tempo de compilação, se os tipos são válidos e compatíveis, aeb são armazenados como valores imediatos (não como referências) e a adição é uma operação simples do processador nesses valores.

Claro, isso é tudo muito teórico. Na prática, muita otimização pode ser feita nesse processo para evitar a maior parte da sobrecarga, e as linguagens dinamicamente tipadas podem ficar bastante rápidas.

solendil
fonte
1
Truques como caches inline polimórficos podem melhorar muito o desempenho. Os escritos de David Ungar (Self) e Eliot Miranda (máquinas virtuais Squeak, Visual Works Smalltalk) são os mais informativos em relação ao desempenho dinâmico da linguagem.
Frank Shearar
0

Todo valor é armazenado junto com seu tipo, que é necessário inspecionar primeiro. Também as conversões dizem que da string para o número passam por inspeção, em tempo real.

Joop Eggen
fonte
Sim, é isso, é apenas uma verificação de tempo de execução, nada extravagante.
anon