Почему динамически типизированные языки медленны?

Что затрудняет ускорение динамически типизированных языков по сравнению со статически типизированными языками. Другими словами, что является свойством свойства статически типизированных языков, которые упрощают их оптимизацию для скорости выполнения?

Ответы

Ответ 1

При обращении к атрибутам/методам в статически типизированных языках поиск обычно сводится к статическому адресу функции. Даже в случае виртуальных методов, которые медленнее, поиск просто считывает смещение от vtable.

В динамических языках имена основаны на строках. Хотите посмотреть foo.bar? Найдите foo в таблице хэшей локальной переменной, затем найдите bar в хэш-таблице foo. В некоторых динамических языках, таких как Python и Ruby, могут быть дополнительные вызовы lookups/method для реализации динамически генерируемых атрибутов.

Все эти поиски очень сложно сделать быстро. Python имеет одну из самых хорошо настроенных реализаций хеш-таблиц в мире, и JavaScript заработал миллионы долларов исследовательских денег. Эта тактика работает - сравните Chrome JavaScript с IE 5, чтобы увидеть, насколько много, но они намного сложнее, чем просто статические вызовы функций.


Я должен упомянуть, что "динамический" язык может варьироваться. Python имеет несколько различных способов взаимодействия с переменными поисками, что приятно в некоторых случаях, но делает оптимизацию очень сложной. Другие динамические языки, такие как Common Lisp и Smalltalk, могут конкурировать равномерно со статическими языками во многих случаях использования, поскольку динамический поиск/модификации более контролируются.

Ответ 2

Определенные типы оптимизации времени компиляции могут выполняться только в том случае, если известен точный тип переменной.

Динамически типизированные языки также часто добавляют логику для определения типа и обеспечения правильности значения для типа.

Ответ 3

Посмотрите на этот пример python:

def fact(n):
    if n==0:
        return n
    return n*fact(n-1)

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

Ответ 4

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

Статические типизированные языки разрешают все типы во время компиляции, поэтому затраты потребляются спереди, один раз.

Это основная причина, по которой динамически типизированные языки обычно медленнее. Но есть и другие вещи, о которых стоит подумать. Многое зависит от компилятора или интерпретатора, реализации GC, раскладки таблицы рассылки и алгоритмов поиска наряду с другими оптимизациями.

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

Ответ 5

Ваш вопрос немного ушел, поскольку динамически типизированные языки на самом деле не медленны. Многие примеры могут быть на практике, но другие быстрые (где fast означает "разумно сопоставимый с c" или что-то в этом роде, cf common lisp).

Многие динамические языки работают на виртуальной машине или даже интерпретируются, что может привести к замедлению, которое можно избежать. На определенном уровне существуют оптимизации, которые доступны для статических компиляторов языка (или динамических, которые сделали правильные типы promises не динамическими для чего-то), которые невозможны в полностью динамической ситуации.

Однако, если вы думаете о различиях между словами python и С++, например, это не проблема с динамикой и статикой.

Ответ 6

Это потому, что статически типизированные языки часто компилируются в машинный код, тогда как динамически типизированные языки в большинстве случаев выполняются интерпретатором.