Интерпретируемые языки: более высокий уровень быстрее?

Я разработал приблизительно 5 экспериментальных языков и интерпретаторы для них до сих пор, для образования, как хобби и для забавы.

Одна вещь я заметил: подобный блоку язык, показывающий только подпрограммы и условные переходы как структуры, был намного медленнее, чем показ высокоуровневого языка если, в то время как и так далее. Я разработал их обоих одновременно, и оба были интерпретируемыми языками. Я записал интерпретаторы в C++, и я пытался оптимизировать часть выполнения кода, чтобы быть максимально быстро.

Моя гипотеза: почти во всех случаях производительность интерпретируемых языков повышается с их уровнем (высокий/низкий).

  • Действительно ли я в основном прав с этим? (В противном случае, почему?)

Править: Я не упоминал слово, скомпилированное здесь даже однажды, это об интерпретируемом по сравнению с интерпретируемым!

20
задан immersion 5 May 2010 в 18:24
поделиться

9 ответов

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

1
ответ дан 29 November 2019 в 23:19
поделиться

В конечном счете, разбор строки текста на вашем языке займет примерно одинаковое количество времени, независимо от того, говорим ли мы об ассемблере или о The Next Big Thing Language (TNBL). Это неправда в буквальном смысле, но это правда в стиле Turing-esque, Big-O-Notation.

Если (опять же, "примерно") требуется столько же времени, чтобы определить, что означает это:

mov $3, $4, $5

и это:

print "foo"

... тогда давайте представим, что мы пишем Hello World на наших двух языках. Интерпретатору ассемблера придется разбирать гораздо более сложную программу. Скажем, n строк, что в n раз больше, чем TNBL Hello Wolrld. Таким образом, ваши основные накладные расходы в n раз больше.

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

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

12
ответ дан 29 November 2019 в 23:19
поделиться

Я бы сказал, вы примерно наполовину правы. Если вы изобразите скорость интерпретации с уровнем языка по оси X и скоростью выполнения по оси Y, вы получите кривую «ванны» - интерпретация языка чрезвычайно низкого уровня может быть довольно быстрой, а интерпретация чрезвычайно высокой уровень языка может быть довольно быстрым. Между ними интерпретация значительно медленнее.

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

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

Изначально предполагалось, что для большинства JVM расширение.«Управляемая» среда .NET, интерпретаторы байт-кода Smalltalk и т. Д. Подошли бы ко второму случаю. Как быстро обнаружило большинство, кто пытался их разработать, очень трудно поддерживать достаточно низкие затраты на интерпретацию, чтобы добиться этого. У всех, кого я знаю, кто входит в этот класс, внутренний цикл написан на ассемблере вручную и обычно хорошим программистом на ассемблере. Я почти зашел так далеко, что сказал, что если вы попытаетесь использовать язык более высокого уровня (даже C), он будет медленнее, и, вероятно, значительно медленнее (когда вы добавляете накладные расходы для каждые команда ввода, даже одна дополнительная инструкция во внутреннем цикле почти наверняка приведет к измеримому снижению скорости).

1
ответ дан 29 November 2019 в 23:19
поделиться

Как провести честное сравнение?

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

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

0
ответ дан 29 November 2019 в 23:19
поделиться

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

30
ответ дан 29 November 2019 в 23:19
поделиться

Резюме: бенчмаркинг - это сложно. Вы не можете обобщать на основе анекдотов.

Это не правило, подкрепленное доказательствами.

Как вы ставите эксперимент, на основании которого делаете вывод "выше = быстрее"? Есть ли у вас примеры реализации идентичных алгоритмов и наборы тестов, позволяющие объективно оценить один интерпретируемый язык в сравнении с другим?

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

Например, если в одном интерпретируемом языке есть оператор quicksort, вы можете подумать: "Ага! Быстрее!", чем в языке, где сортировку приходится выполнять вручную. Однако в худшем случае производительность quicksort составляет O(n^2). Если я передам вашей высокоуровневой операции пример наихудшего набора данных, то другой реализованный вручную merge sort побьет ее.

0
ответ дан 29 November 2019 в 23:19
поделиться

Предполагая, что оба они реализованы примерно одинаково, с неоптимизированным языком низкого уровня, а язык высокого уровня не расширен до промежуточного кода более низкого уровня - «вероятно '.

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

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

Я скажу, что проще реализовать более быстрый язык высокого уровня. (по моему ограниченному опыту)

0
ответ дан 29 November 2019 в 23:19
поделиться

Что ж, очевидно, это будет зависеть от того, как вы реализовали различные языки.

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

1
ответ дан 29 November 2019 в 23:19
поделиться

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

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

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

4
ответ дан 29 November 2019 в 23:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: