Как проверяется тип в интерпретаторе / компиляторе динамического языка, таком как JavaScript?

11

В динамических языках, таких как JavaScript или Python, тип переменной определяется во время выполнения. Это одна из причин, почему они медленнее, чем типизированные языки, такие как Java.

Как выполняется проверка типа? Какова основная причина медленного процесса?


источник
Они не медленнее, потому что они динамичны, они медленнее, потому что их сложнее сделать быстрее. JavaScript на самом деле самый оптимизированный и довольно быстрый.
Дерек Лиц

Ответы:

5

В этом вопросе путаница.

Существует предположение, что проверка типов выполняется медленно, что не всегда так.

Вопрос также , кажется, путают процесс типа отправки с проверкой типов , и это две разные вещи. Один - это процесс, который выполняется во время выполнения, другой - процесс во время компиляции. Я подозреваю, что вопрос действительно касается отправки типа.

Именно диспетчеризация типов может привести к накладным расходам во время выполнения, потому что вычисления тратят время с инструкциями, которые динамически определяют, какое действие предпринять, основываясь на типах значений, которые он видит во время выполнения. например, в динамическом языке, если я применяю «+» к двум вещам, я могу иметь в виду добавление чисел или конкатенацию строк, поэтому мне нужно потратить время на изучение того, что под рукой, чтобы решить, что делать. Существуют стратегии оценки, которые могут снизить стоимость динамической отправки. (например, отслеживание JIT)

Что касается проверки типов в JavaScript, см .: http://www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-flow-typing-theory/ . Для более общего обзора того, как работают средства проверки типов, стандартные учебники по языку программирования будут охватывать алгоритмы. Например, http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/

dyoo
источник
Я также написал небольшой опрос о трассировке JIT и динамических языков в hashcollision.org/comprehensive/tracing.pdf
Интерпретатор Javascript несет биты тега с каждым значением для отправки типа. Не могли бы вы подробнее остановиться на этом? Например, что такое использование битов тегов? Бит соответствует типу?
Понятие типа не всегда связано с представлением. Например, у нас может быть понятие типа «миля» против типа «километр», и разумно иметь язык, который может статически определять во время компиляции, являются ли вычисления неправильным применением операций со значениями, которые портят типы , Вы можете себе представить, что они будут иметь одинаковое представление, и если компилятор может гарантировать, что во время компиляции они никогда не смешиваются, то нет никаких причин, по которым значения будут нуждаться в дополнительной маркировке в представлении.
1
Продолжение: но часто, особенно в динамических языках, вы хотите представлять значения разных типов. Есть несколько способов сделать эту дискриминацию. Теги типа распространены, но есть и другие методы. Например, вы можете поместить определенные типы в заблокированные области памяти. См. «Представление информации о типах в динамически типизированных языках». lambda-the-ultimate.org/node/3912 для всестороннего обзора методов представления.
7

По сути, в нетипизированных языках каждая ссылка указывает на объект, который содержит как тип, так и значение. Например, var a = 3указывает на экземпляр, который содержит значение 3 и тип int, если вы делаете a = "bla", ссылка обновляется на экземпляр, который содержит строку «bla» и строку типа, старый объект отбрасывается и т. Д ...

Это медленно, потому что каждый раз, когда необходимо выполнить операцию (например a + b) с этим базовым типом, среда выполнения должна сначала разыменовать объекты, проверить совместимость их типа, выполнить операцию, создать новый объект.

Напротив, a + bв C ++ или Java проверяет во время компиляции, что типы являются допустимыми и совместимыми, тогда a и b сохраняются как непосредственные значения (не ссылки), и сложение является простой операцией процессора над этими значениями.

Конечно, это все очень теоретически. На практике в этом процессе можно провести большую оптимизацию, чтобы избежать большинства накладных расходов, а языки с динамической типизацией могут работать довольно быстро.

solendil
источник
1
Такие хитрости, как полиморфные встроенные кэши, могут значительно улучшить производительность. Работы Дэвида Унгара (Self) и Элиота Миранды (Squeak, Visual Works Smalltalk виртуальные машины) наиболее информативны в отношении динамической производительности языка.
Фрэнк Шиарар
0

Каждое значение хранится вместе с его типом, который необходимо проверить первым. Также преобразования, скажем, из строки в число проходят проверку на лету.

Joop Eggen
источник
Да, это так, это просто проверка во время выполнения, ничего особенного.
Anon