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

Я читал о плюсах и минусах интерпретируемых языков, и один из самых распространенных минусов-медлительность, но почему программы на интерпретируемых языках медленно?

15 ответов


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

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

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

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

Итак, немного неверно говорить, что язык медленно, а это контекст, в котором он работает, что медленный.

C# не является интерпретируемым языком, даже если он использует промежуточный язык (IL), это JITted для собственных инструкций перед выполнением, поэтому он имеет некоторые того же снижения скорости, но не все, но я бы поспорил, что если вы построите полноценный интерпретатор для C# или C++, он будет работать медленнее.

и просто для ясности, когда я говорю "медленно", это, конечно, относительный термин.


все ответы, похоже, упускают настоящий важный момент здесь. Это подробно, как реализуется" интерпретируемый " код.

интерпретируемые языки медленнее, потому что их метод, объект и глобальная модель пространства переменных динамичны. Это требует много дополнительных поисков хэш-таблицы для каждого доступа к переменной или вызову метода. Здесь проходит большая часть времени. Это болезненный случайный поиск памяти, который действительно болит, когда вы получаете кеш-промах L1/L2.

Google Javascript Core8 настолько быстр и нацелен почти на скорость C для простой оптимизации: они принимают модель объектных данных как фиксированную и создают внутренний код для доступа к ней, как структура данных собственной скомпилированной программы. Когда новая переменная или метод добавляется или удаляется, весь скомпилированный код отбрасывается и компилируется снова.

методика хорошо объяснена в статье Дойча / Шиффмана "эффективная реализация системы Smalltalk-80".

вопрос почему php, python и ruby не делают этого довольно просто ответить: техника чрезвычайно сложна для реализации.

и только у Google есть деньги, чтобы заплатить за JavaScript, потому что быстрый браузер на основе интерпретатора JavaScript является их фундаментальной потребностью их миллиардной бизнес-модели.


думаю интерпретатором в качестве эмулятора для машины вас нет

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

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

это, очевидно, осложняется компиляторами JIT (как раз вовремя), которые имеют Java, C# и другие. Теоретически они так же хороши, как компиляторы "AOT" ("в одно время"), но на практике эти языки работают медленнее и ограничены необходимостью использования компилятора во время выполнения программы. Но если вы скажете что-то из этого здесь, так что будьте готовы привлечь бешеные защитники JIT, которые настаивают на том, что нет теоретической разницы между JIT и AOT. Если вы спросите их, так ли быстры Java и C#, как C и c++, они начнут оправдываться и немного успокоятся. :-)

Итак, C++ полностью правит в играх, где всегда можно использовать максимальное количество доступных вычислений.

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


Это хороший вопрос, но должен быть сформулирован немного иначе на мой взгляд, например: "почему интерпретируемых языках медленнее, чем компилируемые языки?"

Я думаю, что это распространенное заблуждение, что интерпретируемые языки медленны сами по себе. Интерпретируемые языки не медленно, но, в зависимости от варианта использования, может быть медленнее чем скомпилированная версия. В большинстве случаев интерпретируемые языки на самом деле быстро достаточно!

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


цикл a 100 раз, содержимое цикла интерпретируется 100 раз в код низкого уровня.

не кэшируется, не используется повторно, не оптимизирован.

проще говоря, компилятор интерпретирует один раз в код низкого уровня

Edit, после комментариев:

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

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


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

тогда есть виртуальные машины, которые понимают различные двоичные инструкции (например, Java и .NET), но они должны быть переведены на лету на машинные инструкции Just-In-Compiler (JIT). Это почти так же быстро (даже быстрее в некоторых конкретных случаях, потому что компилятор имеет больше информация, чем статический компилятор о том, как используется код.)

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

но интерпретируемые языки часто достаточно быстро для целей, для которых они используются. Веб-приложения неизменно связаны IO (обычно доступ к базе данных), который на порядок медленнее, чем любой интерпретатор.


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

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


от about.com:

обрабатывается интерпретируемый язык во время выполнения. Каждая строка прочитана, проанализировано и выполнено. Имея повторная обработка строки каждый раз в цикле что делает интерпретируемые языки такими медленный. Эти накладные расходы означают, что интерпретируемый код выполняется между 5 - 10 раз медленнее, чем скомпилированный код. Этот интерпретируемые языки, такие как Basic или JavaScript самые медленные. Их преимущество-не нужно после перекомпиляции изменения и это удобно, когда вы учитесь программировать.

5-10 раз медленнее не обязательно верно для таких языков, как Java и C#, однако. Они интерпретируются, но компиляторы just-in-time может генерировать инструкции машинного языка для некоторых операций, значительно ускоряя процесс (иногда около скорости скомпилированного языка).


интерпретируемые языки должны читать и интерпретировать исходный код во время выполнения. При скомпилированном коде большая часть этой интерпретации выполняется раньше времени (во время компиляции).


очень мало современных скриптовых языков are "интерпретируется" в эти дни; они обычно компилируются на лету, либо в машинный код, либо в какой-то промежуточный язык байт-кода, который (более эффективно) выполняется на виртуальной машине.

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


читать это Плюсы И Минусы Интерпретируемых Языков

Это соответствующая идея в этом посте для вашей проблемы.

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


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

Update: нет, я не видел, что мой ответ в какой-то степени совпадает с принятым; -)


да, интерпретируемые языки медленные...

однако рассмотрим следующее. Мне нужно было решить одну проблему. Мне потребовалось 4 минуты, чтобы решить проблему в Python, и программа заняла 0,15 секунды для запуска. Затем я попытался написать его на C, и я получил время выполнения 0,12 секунды, и мне потребовался 1 час, чтобы написать его. Все это потому, что практическим способом решения проблемы было использование хэш-таблиц, а хэш-таблица все равно доминировала во время выполнения.


в Википедии написано,

интерпретация кода медленнее, чем запуск скомпилированного кода, потому что интерпретатор должен анализировать каждый оператор в программе каждый раз, когда он выполняется, а затем выполнять желаемое действие, тогда как скомпилированный код просто выполняет действие в фиксированном контексте, определенном компиляцией. Этот анализ называется "пояснительная накладные". Доступ к переменным также медленнее в интерпретаторе поскольку сопоставление идентификаторов с хранилищами должно выполняться неоднократно во время выполнения, а не во время компиляции.

передать этот IBM doc,

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

в Java, хотя он рассматривается как интерпретируемый язык, он использует JIT (Just-In-Time) компиляция, которая смягчает вышеуказанную проблему, используя метод кэширования для кэширования скомпилированного байт-кода.

компилятор JIT считывает байт-коды во многих разделах (или полностью, редко) и компилирует их динамически в машинный код, чтобы программа могла работать быстрее. Это может быть сделано для каждого файла, для каждой функции или даже для любого произвольного фрагмента кода; код может быть скомпилирован, когда он собирается быть выполнен (отсюда и название "just-in-time"), и затем кэшируется и повторно используется позже без необходимости перекомпиляции.