Я сравниваю две технологии, чтобы получить рекомендацию, для которой одна из них должна использоваться компанией. Код технологии A интерпретируется, а код технологии B компилируется в машинный код. В моем сравнении я утверждаю, что технология B в целом будет иметь лучшую производительность, поскольку она не требует дополнительных затрат на процесс интерпретации. Я также утверждаю, что, поскольку программа может быть написана разными способами, все же возможно, что программа, написанная на технологии A, может превзойти программу, написанную на технологии B.
Когда я представлял этот отчет на рассмотрение, рецензент заявил, что я не представил четкой причины, по которой в целом издержки процесса интерпретации были бы достаточно большими, чтобы мы могли сделать вывод, что производительность технологии B будет лучше.
Итак, мой вопрос: можем ли мы когда-нибудь сказать о производительности скомпилированных / интерпретированных технологий? Если мы можем сказать, что компилирование обычно быстрее, чем интерпретируется, как я могу убедить рецензента в моей точке зрения?
Ответы:
Нет.
В целом, эффективность языковой реализации зависит, прежде всего, от количества денег, ресурсов, рабочей силы, исследований, разработок и разработок, потраченных на нее.
И, в частности, производительность конкретной программы в первую очередь зависит от количества мыслей, заложенных в ее алгоритмах.
Есть несколько очень быстрых интерпретаторов и некоторые компиляторы, которые генерируют очень медленный код.
Например, одна из причин, по которой Forth по-прежнему популярен, заключается в том, что во многих случаях интерпретируемая программа Forth работает быстрее, чем эквивалентная скомпилированная программа на C, в то время как пользовательская программа, написанная на Forth плюс написанный интерпретатор Forth в C меньше, чем пользовательская программа, написанная на C.
источник
Обобщения и конкретные сценарии буквально противоположны.
Вы, кажется, противоречат себе. С одной стороны, вы хотите сделать общее утверждение о интерпретируемых и скомпилированных языках. Но с другой стороны, вы хотите применить это общее утверждение к конкретному сценарию, включающему Технологию A и Технологию B.
Когда вы применяете что-то к конкретному сценарию, оно больше не обобщается . Таким образом, даже если вы можете утверждать, что интерпретируемые языки в целом медленнее , вы все равно не решитесь. Ваш рецензент не заботится об обобщениях. Вы делаете анализ двух очень специфических технологий. Это буквально противоположно обобщению.
источник
Как правило, интерпретируемая программа примерно в 2–10 раз медленнее, чем написание программы на главном языке переводчика, при этом интерпретаторы для более динамичных языков работают медленнее. Это связано с тем, что интерпретируемая программа должна выполнять всю фактическую работу, но дополнительно имеет накладные расходы на интерпретацию.
В зависимости от структуры переводчика, могут быть очень существенные различия. Есть две противоречивые школы дизайна интерпретатора: одна говорит, что коды операций должны быть как можно меньше, чтобы их было легче оптимизировать, другая говорит, что коды операций должны быть как можно больше, чтобы мы могли больше работать с переводчиком. Когда структура вашей программы соответствует философии переводчика, накладные расходы становятся незначительными.
Например, Perl - это интерпретируемый язык, ориентированный на манипулирование текстом. Идиоматическая Perl-программа, выполняющая текстовые манипуляции, будет не намного медленнее, чем C-программа, и может даже превзойти C-программу в некоторых случаях (возможно, потому что Perl использует другое строковое представление и имеет различные встроенные оптимизации для текста и ввода-вывода). Однако работа с числами в Perl будет невыносимо медленной. Инкремент
++x
- это отдельная инструкция сборки, но он включает несколько обходов указателей и ветвей для интерпретатора Perl. Я недавно портировал связанный с CPU сценарий Perl на C ++ и получил ускорение в 7–20 раз, в зависимости от уровня оптимизации компилятора.Говорить об оптимизации здесь важно, так как отточенный, оптимизированный интерпретатор может разумно превзойти неоптимизирующий наивный компилятор. Поскольку создание оптимизирующего компилятора является сложным и требует больших усилий, маловероятно, что ваша «технология B» имеет такой уровень зрелости.
(Примечание: сайт игры «Тесты компьютерного языка» имеет запутанную структуру, но как только вы дойдете до таблицы времени для одной проблемы, вы заметите, что производительность разных языков повсеместна - часто нет четкой границы производительности между скомпилированными и интерпретированными решениями. Самая важная часть сайта - это не результаты тестов, а обсуждение того, насколько трудны значимые тесты.)
При выборе технологии производительность языковой среды исполнения сама по себе совершенно не имеет значения. Скорее всего, будет важно, чтобы технология соответствовала некоторым базовым ограничениям (наш бюджет составляет $ x, мы должны быть в состоянии выполнить до yyyy-mm-dd, мы должны удовлетворить различные нефункциональные требования), и что она имеет более низкий общая стоимость владения (с учетом производительности разработчика, затрат на оборудование, затрат на бизнес-возможности, риска ошибок и непредвиденных ограничений в технологиях, затрат на обслуживание, затрат на обучение и наем,…). Например, в отрасли, где время выхода на рынок является наиболее важным фактором, технология с наилучшей производительностью разработчиков подойдет лучше всего. Для крупной организации ремонтопригодность и долгосрочные затраты могут быть более интересными.
источник
Вы абсолютно можете сказать что-то о производительности скомпилированных / интерпретированных технологий. Но сначала вы должны определить «производительность». Если вы строите простую в вычислительном отношении встроенную систему, то «производительность», скорее всего, будет зависеть от использования памяти. В то время как вычислительно сложная система, работающая с большими наборами данных, будет определять «производительность» в количестве вычислений за единицу времени, поскольку затраты памяти из JVM или .NET будут незначительными.
Как только вы решите, что такое «производительность», вы можете сказать что-то вроде «у нас будет 50 миллиардов объектов в памяти в любой момент времени, и интерпретируемый techA добавляет дополнительные 8 байтов к каждому объекту для внутреннего управления, что равняется накладным расходам памяти в 400 ГБ» по сравнению с techB, который не добавляет эти данные "
источник
Это технический вопрос, и вы уже получили много хороших технических ответов, но я хотел бы отметить несколько иной аспект вашей ситуации: тот факт, что вы не можете просто основывать решение, такое как «технология А или технология В», чисто по техническим и / или эксплуатационным причинам.
Технические аспекты чего-то подобного - это лишь малая часть решения между А и В. Есть десятки других факторов, которые следует иметь в виду:
Как видите, при принятии такого решения нужно учитывать МНОЖЕСТВО.
Я знаю, что это не дает конкретного ответа на ваш вопрос, но я думаю, что это дает более общее представление о вашей ситуации и особенностях такого решения.
источник
Частичная оценка - это концептуальная основа, относящаяся к интерпретаторам и составителям.
Языки программирования являются спецификациями (написанными в некоторых отчетах, таких как R5RS или n1570 ). Это не программное обеспечение, поэтому даже не имеет смысла говорить о производительности . Но некоторые языки программирования могут иметь несколько реализаций, включая интерпретаторы и компиляторы .
Даже в традиционно скомпилированных языках (то есть языках, реализации которых часто являются компиляторами), таких как C, некоторые части часто интерпретируются. Например, строка управления форматом printf (определенная в стандарте C) часто «интерпретируется» ( стандартной библиотекой C , которая имеет
printf
функцию, использующую методы переменных аргументов), но некоторые компиляторы (включая GCC ) могут - в определенных ограниченных кейсы - оптимизировать его и «скомпилировать» в вызовы более низкого уровня.И некоторые реализации, даже внутри «интерпретаторов», используют методы компиляции JIT (поэтому генерируйте машинный код во время выполнения ). Хороший пример - Луаджит . Другие реализации (например, Python, Ocaml, Java, Parrot, Lua) переводят исходный код в байт-код, который затем интерпретируется.
SBCL - это «компилятор» Common Lisp, который динамически переводит каждое взаимодействие REPL (и вызовы в
eval
etc ...) в машинный код. Итак, вы чувствуете, что это переводчик. Большинство реализаций JavaScript в браузерах (например, v8 ) используют методы JIT-компиляции.Другими словами, разница между интерпретаторами и компиляторами очень нечеткая (на самом деле между ними существует континуум), и, практически говоря, большинство реализаций на языке программирования часто имеют как интерпретатор, так и аспект компилятора (по крайней мере, для байтового кода).
Реализация может быть быстрой или медленной независимо от использования большинства методов, подобных «компилятору» или «интерпретатору».
Некоторые языковые особенности предпочитают интерпретирующий подход (и могут быть эффективно скомпилированы только посредством анализа всей программы ).
Для некоторых типов задач стоит разработка программного обеспечения с некоторыми метапрограммирующими подходами, что дает важные ускорения. Вы можете себе представить, что при наличии определенного ввода ваша программа динамически генерирует специализированный код для его обработки. Это даже возможно с C или C ++ (либо используя некоторую библиотеку JIT, либо генерируя некоторый код C, компилируя его как плагин, который загружается динамически).
Смотрите также этот связанный вопрос о Python, и что
источник
Для такого кода
A = A + B
, который может компилироваться до одной или двух машинных инструкций, каждая из которых занимает определенное количество циклов. Ни один переводчик не может сделать то же самое в этом количестве циклов по простой причине.Интерпретатор также выполняет собственный набор команд (назовите их байт-кодами, p-кодами, промежуточным языком и т. Д.). Каждый раз, когда он видит байт-код, такой как ADD, он должен каким-то образом искать его и переходить к коду, который выполняет сложение.
В следующий раз, когда он его увидит, ему придется повторить этот поиск, если только у него не будет способа вспомнить предыдущий поиск. Если у него есть способ запомнить предыдущий поиск, это уже не то, что мы называем «интерпретатором», а скорее компилятор «точно в срок» или JITter.
С другой стороны...
Для кода, например
callSomeFunction( ... some args ...)
, сколько циклов тратится между вводом этого кода и выходом из него? Все зависит от того, что происходит внутриcallSomeFunction
. Это может быть несколько, и это может быть триллионы, даже еслиcallSomeFunction
он сам скомпилирован. Если это много, нет смысла обсуждать стоимость интерпретации этой строки кода - деньги находятся в другом месте.Помните, что интерпретируемые языки имеют свою ценность, например, нет необходимости их компилировать. («Компиляция» поверхностного синтаксиса в байтовые коды занимает тривиальное время. Возьмем, например, R или MATLAB.)
Кроме того, для интеллектуальных уровней программирования необходима гибкость. В Обществе разума Мински , глава 6.4 B- Brain, есть программы A, которые имеют дело с миром, и есть программы B, которые имеют дело с программами A, и могут быть другие уровни. Программы, которые пишут и управляют другими программами, легче выполнять в интерпретирующих системах.
В Лиспе вы можете написать,
(+ A B)
чтобы добавить A и B, но как только он будет записан, у вас есть только выбор: запустить его или нет. Вы также можете написать,(eval (list '+ 'A 'B))
которая создает программу, а затем выполняет ее. Это может создать что-то другое.Предметом программы является другая программа . Это легче писать на интерпретируемом языке (хотя, как указывает Йорг, более новые версии Lisp, хотя и имеют
eval
, компилируют на лету, поэтому они не имеют потери скорости интерпретации).источник
eval
иapply
функции, которые являются переводчиками.eval
это не интерпретируется. И ни один не являетсяapply
. Конечно, есть реализации, которые содержат интерпретаторы, но SBCL - нет.eval
, не интерпретируют ред . Это интерпретируют эр .В некотором роде, это зависит, но, как правило, скомпилированная среда, будь то с помощью JIT или статически скомпилированной среды, будет быстрее для многих задач, требующих большого объема вычислений, - для простоты того же языка.
Частично причина в том, что интерпретируемые языки должны иметь цикл-интерпретатор, который читает инструкцию, выбирает соответствующее действие и выполняет его. В лучшем случае, например, при интерпретации байт-кода Python или Java (как это делала старая JVM), у него есть накладные расходы, состоящие из нескольких инструкций, и он разрушает предсказатель ветвления - без последнего вы можете ожидать огромных штрафов из-за неправильных предсказаний. Даже очень тупой JIT должен значительно ускорить это.
Тем не менее, интерпретируемый язык может обмануть. Например, Matlab оптимизировал подпрограммы для умножения матриц, и с небольшими изменениями вы можете получить код, работающий на графическом процессоре (отказ от ответственности: я работаю на nVidia - любое мнение, высказанное здесь, является моим и не отражает точку зрения моего работодателя). Таким образом, вы можете написать короткий и мощный код высокого уровня, не беспокоясь о деталях - кто-то позаботился об этом и потратил время и ресурсы на его оптимизацию на языке низкого уровня. В этом нет ничего унаследованного, и это не мешает, например, Matlab JIT-коду, но часто нет причин, так как накладные расходы на вызов высокоуровневой подпрограммы минимальны по сравнению со временем, затрачиваемым на низкоуровневые.
TL; DR - скомпилированные программы имеют огромный выигрыш в производительности по сравнению с интерпретируемыми (сравнение яблок с яблоками см. В PyPy Speed ). Однако скорость исполняемого файла - только часть проблемы, и она может не сильно повлиять на общую скорость (если время в основном проводится в библиотеках). Также реализация имеет значение.
источник
Ваше предположение обосновано, хотя это предположение.
Я не собираюсь останавливаться на причинах, почему скомпилированный код должен быть быстрее интерпретируемого кода: если вы знаете, как работают компьютеры, это будет очевидно. Разница может составлять порядки величин для определенных типов проблем. Если ваш рецензент серьезно оспаривает это общее дело, он не знает, о чем говорит.
Однако они могут понять, насколько значительна разница в типе приложения, которое вы разрабатываете. Если это в основном ввод-вывод или вызовы скомпилированных библиотек, и он не требует больших вычислений, издержки процесса интерпретации могут быть незначительными.
Но смысл моего поста таков: вам, как эксперту в области ИТ, часто будут предлагать оперативные решения, основанные на общих знаниях о том, как все должно работать. Проведение определенного теста может дать вам более точный ответ, но это будет стоить намного дороже, и вы не попадете туда первым.
Но время от времени тебя ловят. Это случилось со мной. Вы делаете хорошее предположение, а затем обнаруживаете, что не приняли во внимание глупость мира.
Но я не могу объяснить, как мой любимый мультфильм Дилберта всех времен. Ничто не показывает лучше, чем это опасности быть умным задницей.
TL; DR: ты должен быть прав, но на всякий случай проверь реальный мир.
источник
Если вы не используете что-то экзотическое, ваша проблема не будет связана с производительностью интерпретируемого языка A и скомпилированного языка B.
Потому что, если вы / ваша команда знаете A, а не B, и поэтому пишете код лучше на A, чем на B, у вас может получиться намного лучшая производительность на A, чем на B. Если у вас есть люди, имеющие опыт работы с одним языком, и язык / библиотеки могут это сделать работа вам нужна, придерживайтесь ее.
Вот ссылка о регулярных выражениях на разных языках; вы увидите, что регулярные выражения реализованы лучше в некоторых языках, даже если они скомпилированы или нет: http://benchmarksgame.alioth.debian.org/u64q/performance.php?test=regexdna
источник
Я думаю, что не очень хорошая идея говорить о производительности двух технологий, основываясь только на том факте, что одна компилируется, а другая интерпретируется. Как указано в других ответах, это может зависеть от области применения (некоторые языки могут быть оптимизированы для выполнения некоторых операций очень быстро и выполнения других задач медленнее), а также от опыта людей, которые собираются использовать эту технологию.
Я не думаю, что разумно ожидать, что вы получите повышение производительности, если вы возьмете несколько превосходных интерпретируемых языковых кодеров и дадите им некоторые технологии, с которыми они не знакомы - возможно, теоретически последнее МОЖЕТ привести к повышению производительности, но на самом деле, без необходимых навыков и опыта вы не сможете использовать все возможности оптимизации.
От одного из известных сотрудников компании в Силиконовой долине я также слышал, что они предпочитают язык, который проще использовать, так как более дорогостоящим и хлопотным платят некоторые опытные разработчики, чтобы поддерживать сложный, но высоко оптимизированный код, чем просто купите больше буровой установки, чтобы справиться с менее эффективной реализацией, что также следует учитывать при выборе технологии.
источник
Однажды мне пришлось сделать подобное широкое заявление, чтобы оправдать большое решение.
Во-первых, они могут не захотеть верить скромному инженеру, поэтому я нашел несколько сопоставимых тестов производительности и процитировал их. Их много, от таких людей, как Microsoft, или от известных университетов. И они скажут что-то вроде: метод A в 3-10 раз быстрее, чем метод B, в зависимости от переменных X и Y.
Во-вторых, вам может потребоваться выполнить собственный тест, возможно, используя представительный фрагмент кода, о котором идет речь, или что-то подобное, что у вас уже есть. Запустите его 1000 раз за ночь, так что разница действительно ощутима.
На этом этапе разница (или ее отсутствие) между A и B должна быть настолько ясной, что вам нужно только представить ее. Так что форматируйте результаты четко, с диаграммами, если это возможно, излагая все предположения и определяя все используемые данные.
источник
Я бы сказал, что любой динамический язык имеет преимущество перед статически скомпилированными: «Оптимизация во время выполнения»
Это одна из причин, почему Java может быть быстрее, чем C ++
Да, загрузка динамически типизированного языка всегда будет стоить перевода и будет в невыгодном положении. Но когда он запущен, интерпретатор может профилировать и расширять частые пути кода с помощью информации времени выполнения, которой у статических языков никогда не будет
ПРИМЕЧАНИЕ. Итак, Java - это интерпретируемый, а не динамический язык. Но это отличный пример того, что вы можете ускорить с информацией времени выполнения
источник
Это был бы мой подход:
В общем случае интерпретаторы компилируются, поэтому каждая интерпретируемая технология является ничем иным, как скомпилированной технологией, если смотреть на нее на низком уровне. Следовательно, скомпилированные технологии - это все больше и больше возможностей, и вы никогда не станете хуже, если вы умны (а вы в целом) Это зависит от того, сколько информации доступно во время компиляции и сколько информации доступно только во время выполнения и насколько хороши компиляторы и интерпретаторы, но теоретически всегда должно быть возможно, по крайней мере, сравнить производительность любого интерпретатора с подходящим компилятором, только потому, что интерпретаторы изготовлены компиляторами. То, что это возможно, не значит, что дело касается ваших техников А и В.
На практике просто расскажите рецензенту обо всех доступных тестах, где сравниваются скомпилированные и интерпретированные системы. Затем попросите его предложить интерпретатора, который превосходит ваш оптимизированный ассемблерный код конкретного алгоритма.
Можно добавить, что любое такое общее утверждение совершенно не помогает при сравнении двух конкретных технологий A и B. Выбор A и B имеет гораздо большее значение, чем их интерпретация или компиляция.
источник