Кажется редким читать "виртуальную машину" на Python, в то время как в Java "виртуальная машина" используется постоянно.
Оба интерпретируют байтовые коды; зачем называть одну виртуальной машиной, а другую - переводчиком?
Кажется редким читать "виртуальную машину" на Python, в то время как в Java "виртуальная машина" используется постоянно.
Оба интерпретируют байтовые коды; зачем называть одну виртуальной машиной, а другую - переводчиком?
Виртуальная машина - это виртуальная вычислительная среда с определенным набором атомно-корректных инструкций, которые поддерживаются независимо от какого-либо конкретного языка, и обычно это воспринимается как песочница для себя. VM аналогична набору команд конкретного ЦП и имеет тенденцию работать на более фундаментальном уровне с очень основными строительными блоками таких инструкций (или байтовых кодов), которые не зависят от следующего. Инструкция выполняет детерминистически основанную только на текущем состоянии виртуальной машины и не зависит от информации в другом месте потока команд в этот момент времени.
С другой стороны, интерпретатор более изощрен в том смысле, что он предназначен для синтаксического анализа потока некоторого синтаксиса, который имеет определенный язык и определенный грамматик, который должен быть декодирован в контексте окружающих токенов. Вы не можете смотреть каждый байт или даже каждую строку отдельно и точно знать, что делать дальше. Токены на языке не могут быть взяты изолированно, как они могут относиться к инструкциям (байтовые коды) виртуальной машины.
Компилятор Java преобразует язык Java в поток байтового кода, отличный от компилятора C, преобразует C-языковые программы в код сборки. Интерпретатор, с другой стороны, на самом деле не преобразовывает программу в какую-либо четко определенную промежуточную форму, она просто принимает программные действия в процессе интерпретации источника.
Еще одно испытание разницы между виртуальной машиной и интерпретатором заключается в том, считаете ли вы ее независимым от языка. То, что мы знаем как виртуальная машина Java, на самом деле не является специфичным для Java. Вы можете сделать компилятор с других языков, что приведет к байт-кодам, которые могут быть запущены на JVM. С другой стороны, я не думаю, что мы действительно подумали бы о "компиляции" другого языка, кроме Python, в Python для интерпретации интерпретатором Python.
Из-за сложности процесса интерпретации это может быть относительно медленный процесс... в частности, анализ и идентификация языковых токенов и т.д. и понимание контекста источника, позволяющего выполнить процесс выполнения в рамках переводчик. Чтобы ускорить такие интерпретируемые языки, мы можем определить промежуточные формы предварительно проанализированного, предварительно обозначенного исходного кода, который более легко интерпретируется напрямую. Такая бинарная форма по-прежнему интерпретируется во время выполнения, она только начинается с гораздо менее удобочитаемой формы для повышения производительности. Однако логика, выполняющая эту форму, не является виртуальной машиной, потому что эти коды по-прежнему не могут быть взяты изолированно - контекст окружающих токенов все еще имеет значение, они сейчас находятся в другой более эффективной компьютерной форме.
В этом сообщении "виртуальная машина" относится к процессам виртуальных машин, а не к системных виртуальных машин, таких как Qemu или Virtualbox. Виртуальная машина процесса просто программа, которая обеспечивает общую среду программирования - программу который может быть запрограммирован.
Java имеет интерпретатор, а также виртуальную машину, а Python имеет виртуальную машины, а также переводчика. Причина "виртуальной машины" - это больше общий термин в Java и "интерпретатор" - более общий термин в Python. сделать главное различие между двумя языками: статическая типизация (Java) и динамической типизации (Python). В этом контексте термин "тип" относится к примитивные типы данных - типы, которые предполагают размер памяти в памяти данные. У виртуальной машины Java это легко. Это требует от программиста укажите примитивный тип данных для каждой переменной. Это обеспечивает достаточную информация для байт-кода Java не только должна быть интерпретирована и выполнена Java, но даже для скомпилированных в машинные инструкции. Виртуальная машина Python более сложна в том смысле, что она принимает дополнительная задача приостановки до выполнения каждой операции для определения примитивные типы данных для каждой переменной или структуры данных, участвующих в операция. Python освобождает программиста от мышления с точки зрения примитивных данных типов и позволяет выполнять операции на более высоком уровне. Цена эта свобода - это производительность. "Интерпретатор" - предпочтительный термин для Python потому что он должен приостановить проверку типов данных, а также потому, что сравнительно сжатый синтаксис динамически типизированных языков хорошо подходит для интерактивные интерфейсы. Там нет технического барьера для создания интерактивного Java-интерфейс, но при этом пытается написать любой статически типизированный код в интерактивном режиме было бы утомительно, так что просто так не делается.
В мире Java виртуальная машина крадет шоу, потому что он запускает программы написанный на языке, который фактически может быть скомпилирован в машинные инструкции, и результат - скорость и эффективность ресурсов. Байт-код Java может быть выполнен виртуальной машиной Java, производительность которой приближается к производительности скомпилированных программ, относительно говоря. Это связано с наличием примитивных данных введите информацию в байт-код. Виртуальная машина Java помещает Java в отдельная категория:
переносимый интерпретируемый статически типизированный язык
Следующей ближайшей задачей является LLVM, но LLVM работает на другом уровне:
переносимый интерпретируемый язык ассемблера
Термин "байт-код" используется как в Java, так и в Python, но не весь байт-код созданы равными. байт-код - это просто общий термин для промежуточных языков используемых компиляторами/переводчиками. Даже компиляторы C, такие как gcc, используют промежуточное язык (или несколько), чтобы выполнить работу. Байт-код Java содержит информация о примитивных типах данных, тогда как байт-код Python этого не делает. В в этом отношении виртуальная машина Python (и Bash, Perl, Ruby и т.д.) действительно является существенно медленнее, чем виртуальная машина Java, или, скорее, она просто больше работы. Полезно рассмотреть, какая информация содержится в разные форматы байткодов:
Чтобы провести реальную аналогию: LLVM работает с атомами, виртуальная машина Java работает с молекулами, а виртуальная машина Python работает с материалами. Поскольку все должно в конечном итоге разлагаться на субатомные частицы (действительные машинные операции), виртуальная машина Python имеет самую сложную задачу.
Intepreters/составители статически типизированных языков просто не имеют одинаковых багажа, которые имеют устные/составители динамически типизированных языков. Программисты статически типизированных языков должны занять слабину, для чего выигрыш - это производительность. Однако, как и все недетерминированные функции тайно детерминированные, так что все языки с динамически типизированными тайнами статически типизированных. Различия в производительности между двумя языковыми семействами поэтому следует выравнивать время, в течение которого Python меняет свое имя на HAL 9000.
Виртуальные машины динамических языков, таких как Python, реализуют некоторые идеализированные логической машины и не обязательно очень близко соответствуют реальным физическое оборудование. Виртуальная машина Java, напротив, более похожа на функциональности для классического компилятора C, за исключением того, что вместо испускания машинных инструкций, он выполняет встроенные процедуры. В Python целое число объект Python с множеством атрибутов и методов, прикрепленных к нему. В Java, int - обозначенное количество бит, обычно 32. Это не справедливое сравнение. Целые числа на Python действительно должны сравниваться с Java Integer класс. Явный "примитивный" тип данных "int" нельзя сравнивать ни с чем в языка Python, потому что на языке Python просто отсутствует этот уровень примитивов, а также байт-код Python.
Поскольку переменные Java явно набраны, можно разумно ожидать что-то вроде Jython, чтобы быть в одном и том же cPython. С другой стороны, виртуальная машина Java, реализованная в Python почти гарантированно будет медленнее, чем грязь. И не ожидайте, что Ruby, Perl и т.д. чтобы лучше ехать. Они не были предназначены для этого. Они были предназначены для "scripting", что и называется программированием в динамическом языке.
Каждая операция, которая происходит на виртуальной машине, в конечном итоге должна ударить по реальному оборудованию. Виртуальные машины содержат предварительно скомпилированные подпрограммы, которые достаточно общие для выполнения любой комбинации логических операций. Виртуальная машина не может испускать новые машинные инструкции, но она, конечно же, выполняет свои собственные процедуры снова и снова в сложных для группы последовательностях. Виртуальная машина Java, виртуальная машина Python и все другие универсальные виртуальные машины там равны в том смысле, что их можно уговорить выполнять любую логику, о которой вы можете мечтать, но они отличаются с точки зрения того, какие задачи они выполняют взять на себя и какие задачи они уходят программисту.
Psyco для Python не является полной виртуальной машиной Python, но точно в срок компилятор, который захватывает обычную виртуальную машину Python в точках, которые она считает может скомпилировать несколько строк кода - в основном петли, где он считает примитивным тип некоторой переменной будет оставаться постоянным, даже если значение изменяется с каждая итерация. В этом случае он может отказаться от некоторых из непрекращающихся типов определение обычной виртуальной машины. Вы должны быть немного осторожны, хотя, чтобы вы не вытащили этот тип из-под ног Psyco. Писко, однако, обычно знает, чтобы просто вернуться к обычной виртуальной машине, если она не полностью уверен, что тип не изменится.
Мораль этой истории заключается в том, что примитивная информация о типе данных действительно полезно для компилятора/виртуальной машины.
Наконец, чтобы выразить все это в перспективе, подумайте об этом: программа Python выполнена с помощью интерпретатора/виртуальной машины Python, реализованного в Java, работающем на Java интерпретатор/виртуальная машина, реализованная в LLVM, запущенная в виртуальной виртуальной машине qemu машина работает на iPhone.
Вероятно, одна из причин различной терминологии заключается в том, что обычно думают о том, чтобы кормить интерпретатор интерпретатора python необработанным человекочитаемым исходным кодом и не беспокоиться о байт-коде и все такое.
В Java вам необходимо явно скомпилировать байт-код, а затем запустить только байт-код, а не исходный код на виртуальной машине.
Хотя Python использует виртуальную машину под обложками, с точки зрения пользователя, большую часть времени можно игнорировать эту деталь.
Интерпретатор, преобразует исходный код в некоторое эффективное промежуточное представление (код) и сразу же выполняет это.
Виртуальная машина, явно выполняет сохраненный предварительно скомпилированный код, созданный компилятором, который является частью системы интерпретатора.
Очень важной характеристикой виртуальной машины является то, что программное обеспечение, запущенное внутри, ограничено ресурсами, предоставляемыми виртуальной машиной. Точно так же он не может вырваться из своего виртуального мира. Подумайте о безопасном выполнении удаленного кода, Java-апплетов.
В случае python, если мы сохраняем файлы pyc, как указано в комментарии к этому сообщению, тогда механизм будет больше похож на VM, и этот байт-код будет выполняться быстрее - он все равно будет интерпретироваться, но из-за большого количества компьютер более дружелюбная форма. Если мы посмотрим на это в целом, PVM станет последним шагом Python Interpreter.
Суть в том, что, ссылаясь на Python Interpreter, это означает, что мы имеем в виду это как целое, и когда мы говорим PVM, это означает, что мы просто говорим о части Python Interpreter, среде выполнения. Подобно Java, мы ссылаемся на разные части: дифференцил, JRE, JVM, JDK и т.д.
Подробнее, Википедия: Interpreter и Виртуальная машина. Еще один здесь. Здесь вы можете найти Сравнение виртуальных машин приложения. Это помогает понять разницу между компиляторами, интерпретаторами и виртуальными машинами.
Термин интерпретатор является устаревшим термином, относящимся к более ранним языковым сценариям оболочки. Поскольку "языки сценариев" превратились в полноценные языки, и их соответствующие платформы стали более сложными и изолированными, различие между виртуальной машиной и интерпретатором (в смысле Python) очень мало или вообще не существует.
Интерпретатор Python по-прежнему функционирует так же, как оболочка script, в том смысле, что он может быть выполнен без отдельного этапа компиляции. Кроме того, различия между интерпретатором Python (или Perl или Ruby's) и виртуальной машиной Java - это в основном детали реализации. (Можно было бы утверждать, что Java более полно изолирован от программ, чем Python, но оба в конечном итоге обеспечивают доступ к базовой архитектуре через собственный интерфейс C.)
Там нет реальной разницы между ними, люди просто следуют соглашениям, которые выбрали создатели.
Чтобы дать глубокий ответ на вопрос "Почему виртуальная машина Java, а интерпретатор Python?" Давайте попробуем вернуться к области теории компиляции в качестве отправной точки обсуждения.
Типичный процесс компиляции программы включает в себя следующие этапы:
a = b + c
является правильным утверждением с точки зрения синтаксиса, но совершенно неверным с семантической точки зрения, если a
было объявлено как константный объект)Хорошо. Теперь давайте определимся с терминами.
Интерпретатор в классическом значении этого слова предполагает выполнение на основе оценки программы, основанной на AST, полученной непосредственно из текста программы. В этом случае программа распространяется в виде исходного кода, а интерпретатор заполняется текстом программы, часто динамическим способом (оператор за оператором или построчно). Для каждого оператора ввода интерпретатор создает свой AST и сразу же оценивает его, изменяя "состояние" программы. Это типичное поведение, демонстрируемое скриптовыми языками. Рассмотрим, например, Bash, Windows CMD и т.д. Концептуально, Python тоже так поступает.
Если мы заменим основанный на AST шаг выполнения на генерацию промежуточного машинно-независимого шага двоичного байт-кода в интерпретаторе, мы разделим весь процесс выполнения программы на две отдельные фазы: компиляция и выполнение. В этом случае то, что раньше было интерпретатором, станет компилятором байт-кода, который преобразует программу из формы текста в некоторую двоичную форму. Затем программа распространяется в этой двоичной форме, но не в форме исходного кода. На пользовательской машине этот байт-код подается в новую сущность - виртуальную машину, которая фактически интерпретирует этот байт-код. За счет этого виртуальные машины также называют интерпретатором байт-кода. Но обратите ваше внимание здесь! Классический интерпретатор - это текстовый интерпретатор, а виртуальная машина - это двоичный интерпретатор ! Это подход, принятый Java и С#.
Наконец, если мы добавим генерацию машинного кода в компилятор байт-кода, мы получим в результате то, что мы называем классическим компилятором. Классический компилятор преобразует исходный код программы в машинный код конкретного процессора. Затем этот машинный код может быть непосредственно выполнен на целевом процессоре без какого-либо дополнительного посредничества (без какого-либо интерпретатора, ни текстового, ни двоичного интерпретатора).
Теперь вернемся к исходному вопросу и рассмотрим Java против Python.
Изначально Java была спроектирована так, чтобы иметь как можно меньше зависимостей реализации. Его дизайн основан на принципе "пиши один раз, беги куда угодно" (WORA). Для его реализации Java изначально была разработана как язык программирования, который компилируется в машинно-независимый двоичный байт-код, который затем может выполняться на всех платформах, поддерживающих Java, без необходимости его перекомпиляции. Вы можете думать о Java так же, как о WORA C++. На самом деле Java ближе к C++, чем к языкам сценариев, таким как Python. Но в отличие от C++, Java была разработана для компиляции в двоичный байт-код, который затем выполняется в среде виртуальной машины, в то время как C++ была разработана для компиляции в машинном коде, а затем непосредственно выполнялась целевым процессором.
Первоначально Python был разработан как своего рода язык программирования сценариев, который интерпретирует сценарии (программы в форме текста, написанного в соответствии с правилами языка программирования). Из-за этого Python изначально поддерживал динамическую интерпретацию однострочных команд или операторов, как это делают Bash или Windows CMD. По той же причине в начальных реализациях Python не было никаких компиляторов байт-кода и виртуальных машин для выполнения такого байт-кода внутри, но с самого начала в Python требовался интерпретатор, который способен понимать и оценивать текст программы Python.
Из-за этого исторически Java-разработчики имели тенденцию говорить о виртуальной машине Java (потому что изначально Java представлял собой пакет компилятора байт- кода Java и интерпретатора байт-кода - JVM), а разработчики Python имели тенденцию говорить о интерпретаторе Python (потому что изначально Python имел не какая-либо виртуальная машина, а была своего рода классическим текстовым интерпретатором, который исполнял программный текст напрямую, без какой-либо компиляции или преобразования в любую форму двоичного кода).
В настоящее время Python также имеет виртуальную машину и может компилировать и интерпретировать байт-код Python. И этот факт делает дополнительные инвестиции в путаницу "Почему виртуальная машина Java, а интерпретатор Python?", Потому что кажется, что реализации обоих языков содержат виртуальные машины. Но! Даже в настоящий момент интерпретация текста программы является основным способом выполнения программ на Python. Реализации Python используют виртуальные машины под капотом исключительно как метод оптимизации. Интерпретация двоичного байт-кода в виртуальной машине намного эффективнее, чем прямая интерпретация исходного текста программы. В то же время присутствие виртуальной машины в Python абсолютно прозрачно как для разработчиков языка Python, так и для разработчиков программ Python. Один и тот же язык может быть реализован в интерпретаторах с виртуальной машиной и без нее. Таким же образом одни и те же программы могут выполняться в интерпретаторах как с виртуальной машиной, так и без нее, и эти программы будут демонстрировать абсолютно одинаковое поведение и одинаково выводить одинаковые выходные данные. Единственным заметным отличием будет скорость выполнения программы и объем памяти, потребляемый интерпретатором. Таким образом, виртуальная машина в Python не является неизбежной частью языкового дизайна, но является необязательным расширением основного интерпретатора Python.
Java можно рассматривать аналогичным образом. Java под капотом имеет JIT-компилятор и может выборочно компилировать методы класса Java в машинный код целевой платформы и затем непосредственно выполнять его. Но! Java по-прежнему использует интерпретацию байт-кода в качестве основного способа выполнения Java-программы. Подобно реализациям Python, которые используют виртуальные машины под капотом исключительно как метод оптимизации, виртуальные машины Java используют компиляторы Just-In-Time исключительно для целей оптимизации. Точно так же, просто из-за того, что прямое выполнение машинного кода как минимум в десять раз быстрее, чем интерпретация Java байт-кода. Как и в случае с Python, наличие JIT-компилятора под капотом JVM абсолютно прозрачно как для разработчиков языка Java, так и для разработчиков программ на Java. Тот же язык программирования Java может быть реализован JVM с JIT-компилятором и без него. Точно так же одни и те же программы могут выполняться в JVM с JIT внутри и без него, и одни и те же программы будут демонстрировать абсолютно одинаковое поведение и одинаково выводить одинаковые выходные данные на обоих входах JVM (с JIT и без него). И, как и в случае с Python, единственное заметное различие между ними заключается в скорости выполнения и объеме памяти, используемой JVM. И, наконец, как и в случае с Python, JIT в Java также является не неизбежной частью языкового дизайна, а просто необязательным расширением основных реализаций JVM.
С точки зрения проектирования и реализации виртуальных машин Java и Python они существенно различаются, хотя (внимание!) Обе остаются виртуальными машинами. JVM является примером низкоуровневой виртуальной машины с простыми базовыми операциями и высокой стоимостью отправки команд. Python, в свою очередь, представляет собой высокоуровневую виртуальную машину, для которой инструкции демонстрируют сложное поведение, а стоимость отправки инструкций не столь значительна. Java работает с очень низким уровнем абстракции. JVM работает с небольшим четко определенным набором примитивных типов и имеет очень тесное соответствие (обычно один к одному) между инструкциями байт-кода и инструкциями собственного машинного кода. Напротив, виртуальная машина Python работает на высоком уровне абстракции, она работает со сложными типами данных (объектами) и поддерживает специальный полиморфизм, в то время как инструкции байт-кода демонстрируют сложное поведение, которое может быть представлено последовательностью нескольких инструкций машинного кода. Например, Python поддерживает математику неограниченного диапазона. Таким образом, Python VM вынуждена использовать длинную арифметику для потенциально больших целых чисел, для которых результат операции может переполнить машинное слово. Следовательно, одна инструкция байт-кода для арифметики в Python может быть представлена в вызове функции внутри Python VM, тогда как в JVM арифметическая операция будет представлена в виде простой операции, выражаемой одной или несколькими собственными машинными инструкциями.
В результате мы можем сделать следующие выводы. Виртуальная машина Java, но интерпретатор Python, потому что:
Поэтому и Java, и Python имеют виртуальные машины, которые являются двоичными интерпретаторами байт-кода, что может привести к путанице, такой как "Почему виртуальная машина Java, но интерпретатор Python?". Ключевым моментом здесь является то, что для Python виртуальная машина не является основным или необходимым средством выполнения программы; это просто необязательное расширение классического текстового интерпретатора. С другой стороны, виртуальная машина является ядром и неизбежной частью экосистемы выполнения Java-программ. Выбор статической или динамической типизации для дизайна языка программирования в основном влияет только на уровень абстракции виртуальной машины, но не определяет, нужна ли виртуальная машина. Языки, использующие обе системы ввода, могут быть скомпилированы, интерпретированы или выполнены в среде виртуальной машины, в зависимости от желаемой модели исполнения.
Не забывайте, что у Python есть компиляторы JIT для x86, что еще больше путает проблему. (См. Psyco).
Более строгая интерпретация "интерпретируемого языка" становится полезна при обсуждении проблем производительности VM, например, по сравнению с Python, Ruby был (есть?), который считается более медленным, поскольку он является интерпретированным языком, в отличие от Python - другими словами, контекст - это все.
Python может интерпретировать код, не компилируя его в байт-код. Java не может.
Python является интерпретируемым языком, в отличие от скомпилированного, хотя различие может быть размытым из-за присутствия компилятора байт-кода. Это означает, что исходные файлы можно запускать напрямую, без явного создания исполняемого файла, который затем запускается.
(из документации).
В Java каждый отдельный файл должен быть скомпилирован в файл .class
, который затем запускается на JVM. Напротив, python делает то, что импортируется вашим основным скриптом, чтобы ускорить последующее использование этих файлов.
Однако в типичном случае большая часть кода на python (по крайней мере, CPython) выполняется на эмулируемой машине стека, в которой инструкции почти идентичны инструкциям JVM, поэтому большой разницы нет.
Однако настоящая причина такого расхождения заключается в том, что с самого начала java маркировался как "переносимый исполняемый байт-код", а python - как динамический интерпретируемый язык с REPL. Имена придерживаются!
Прежде всего, вы должны понимать, что программирование или компьютерная наука вообще не математика, и у нас нет строгих определений для большинства терминов, которые мы часто используем.
теперь на ваш вопрос:
что такое интерпретатор (в области информатики)
Он преобразует исходный код наименьшим исполняемым модулем, а затем выполняет его.
что такое виртуальная машина
в случае JVM виртуальная машина представляет собой программное обеспечение, которое содержит интерпретатор, загрузчики классов, сборщик мусора, планировщик потоков, компилятор JIT и многое другое.
поскольку вы можете видеть, что интерпретатор является частью или JVM, а целая JVM нельзя назвать интерпретатором, потому что она содержит много других компонентов.
зачем использовать слово "интерпретатор" при разговоре о python
с java часть компиляции является явной. python, с другой стороны, не является явным как java о его процессе компиляции и интерпретации, поскольку интерпретация перспективы конечного пользователя является единственным механизмом, используемым для выполнения программ python.
Я думаю, что границы между обоими размыты, люди в основном спорят о значении слова "интерпретатор" и о том, насколько близко язык стоит к каждой стороне спектра "интерпретатор... компилятор". Ни один не делает 100% как бы то ни было. Я думаю, что легко написать реализацию Java или Python, которая имеет любое значение спектра.
В настоящее время и Java, и Python имеют виртуальные машины и байт-код, хотя один из них работает с конкретными размерами значений (например, 32-разрядным целым числом), в то время как другой должен определять размер для каждого вызова, который, по моему мнению, не определяет границу между терминами.
Аргумент о том, что Python не имеет официально определенного байт-кода и существует только в памяти, также не убеждает меня, просто потому, что я планирую разработать устройства, которые будут распознавать только байт-код Python, а часть компиляции будет выполнена на компьютере JS браузера.
Производительность только о конкретной реализации. Нам не нужно знать размер объекта, чтобы иметь возможность работать с ним, и, наконец, в большинстве случаев мы работаем со структурами, а не с базовыми типами. Можно оптимизировать Python VM таким образом, чтобы исключить необходимость создания нового объекта каждый раз во время вычисления выражения путем повторного использования существующего. Как только это будет сделано, не будет глобальной разницы в производительности между вычислением суммы двух целых чисел, и именно здесь Java сияет.
Разницы между ними нет, только некоторые нюансы реализации и отсутствие оптимизации, которые не имеют отношения к конечному пользователю, возможно, в тот момент, когда она начинает замечать отставание в производительности, но опять-таки это проблема реализации, а не архитектуры.
Нет, они оба не интерпретируют байт-код.
Python интерпретирует байт-код, только если вы работаете с pypy. В противном случае он компилируется в C и интерпретируется на этом уровне.
Java компилируется в байт-код.