자바“가상 머신”과 파이썬“인터프리터”의 용어?


207

Java "가상 머신"이 항상 사용되는 동안 파이썬 "가상 머신"을 읽는 것은 드문 것 같습니다.

둘 다 바이트 코드를 해석합니다. 하나는 가상 머신이고 다른 하나는 통역사라고 부르는 이유는 무엇입니까?

답변:


137

가상 머신은 특정 언어와 독립적으로 지원되는 특정 원자 단위로 정의 된 명령어 세트가있는 가상 컴퓨팅 환경이며 일반적으로 자체 샌드 박스로 간주됩니다. VM은 특정 CPU의 명령어 세트와 유사하며 다음 명령어와 독립적 인 명령어 (또는 바이트 코드)의 매우 기본적인 빌딩 블록으로보다 기본적인 수준에서 작동하는 경향이 있습니다. 명령은 가상 머신의 현재 상태에만 기반하여 결정적으로 실행되며 해당 시점의 명령 스트림에있는 다른 정보에 의존하지 않습니다.

반면에 인터프리터는 특정 언어 및 주변 토큰의 컨텍스트에서 디코딩되어야하는 특정 그래머의 일부 구문 스트림을 구문 분석하도록 조정되어 있기 때문에 더 정교합니다. 각 바이트 또는 각 라인을 개별적으로 볼 수 없으며 다음에 수행 할 작업을 정확히 알 수 없습니다. 언어의 토큰은 VM의 명령어 (바이트 코드)와 관련하여 격리 할 수 ​​없습니다.

Java 컴파일러는 Java 언어를 바이트 코드 스트림으로 변환하고 C 컴파일러는 C 언어 프로그램을 어셈블리 코드로 변환합니다. 반면에 통역사는 실제로 프로그램을 잘 정의 된 중간 형식으로 변환하지 않으며 단지 소스를 해석하는 과정에서 프로그램 동작을 취합니다.

VM과 인터프리터의 차이점에 대한 또 다른 테스트는 VM이 ​​언어 독립적이라고 생각하는지 여부입니다. 우리가 Java VM으로 알고있는 것은 실제로 Java에 특정한 것은 아닙니다. JVM에서 실행될 수있는 바이트 코드를 생성하는 다른 언어로 컴파일러를 작성할 수 있습니다. 다른 한편으로, 나는 파이썬 인터프리터가 해석하기 위해 파이썬 이외의 다른 언어를 파이썬으로 "컴파일"할 것이라고 생각하지 않습니다.

해석 과정의 정교함 때문에 이것은 비교적 느린 과정 일 수 있습니다. 특히 언어 토큰을 구문 분석 및 식별하는 등 통역사 내에서 실행 프로세스를 수행 할 수있는 소스의 컨텍스트를 이해합니다. 이러한 해석 된 언어를 가속화하기 위해보다 쉽게 ​​직접 해석되는 사전 구문 분석 된 사전 토큰 화 된 소스 코드의 중간 형식을 정의 할 수 있습니다. 이러한 종류의 이진 형식은 여전히 ​​실행 시간에 해석되며 성능을 향상시키기 위해 사람이 읽을 수있는 형식이 훨씬 적습니다. 그러나 해당 형식을 실행하는 논리는 가상 머신이 아닙니다. 이러한 코드는 여전히 분리되어 사용할 수 없기 때문입니다. 주변 토큰의 컨텍스트는 여전히 중요합니다.


7
나는 파이썬이 바이트 코드, pyc를 생성했다는 인상을 받았거나 당신이 말하는 것은 "그러한 해석 언어를 가속화하는 데 도움이된다. "직접적으로 해석됩니다."
James McMahon

32
@InSciTek Jeff : 당신의 대답에서 파이썬이 가상 머신을 사용한다는 것을 알 수 있는지 확실하지 않습니다.
tzot

3
@TZ-널리 사용되는 Python 구현은 후면 VM이있는 Python 컴파일러입니다. 대화식 모드에서는 인터프리터 프론트 엔드와 컴파일러 백엔드가 모두 하이브리드입니다. 그러나 이들은 구현 선택입니다. 나는 VM의 개념과 인터프리터의 차이점을 설명하려고 노력했다
Tall Jeff

8
On the other hand, I don't think we would really think of "compiling" some other language other than Python into Python for interpretation by the Python interpreter.스칼라가 Java 바이트 코드로 컴파일 된 것처럼 파이썬 바이트 코드로 컴파일 될 수있는 언어를 작성할 수 있습니다. 대화식 모드에서 Python의 대화식 쉘은 입력 한 명령을 바이트 코드로 컴파일하고 해당 바이트 코드를 실행합니다. eval 및 exec를 사용하여 고유 한 셸을 작성할 수 있으며 compile () 내장 함수를 사용하여 문자열을 바이트 코드로 변환 할 수 있습니다.
Lie Ryan

4
@Lie Ryan 예.하지만 JVM에서와 같이 공식적으로 지원되지 않습니다. 파이썬에서 바이트 코드는 문서화되지 않은 구현 세부 사항입니다.
안티몬

159

이 게시물에서 "가상 머신"은 Qemu 또는 Virtualbox와 같은 시스템 가상 머신이 아닌 프로세스 가상 머신을 나타냅니다. 프로세스 가상 머신은 단순히 프로그래밍 가능한 프로그램 인 일반적인 프로그래밍 환경을 제공하는 프로그램입니다.

Java에는 가상 머신뿐만 아니라 인터프리터도 있고 Python에는 인터프리터뿐만 아니라 가상 머신도 있습니다. "가상 머신"이 Java에서 더 일반적인 용어이고 "인터프리터"가 파이썬에서 더 일반적인 용어 인 이유는 정적 타이핑 (Java)과 동적 타이핑 (Python)의 두 언어의 주요 차이점과 관련이 있습니다. 이와 관련하여 "유형"은 기본 데이터 유형 (데이터의 메모리 내 저장 크기를 제안하는 유형)을 나타냅니다 . 자바 가상 머신은 쉽다. 프로그래머는 각 변수의 원시 데이터 유형을 지정해야합니다. 이것은 자바 바이트 코드가 자바 가상 머신에 의해 해석되고 실행될뿐만 아니라 머신 명령어컴파일되기에 충분한 정보를 제공합니다.. Python 가상 머신은 각 작업을 실행하기 전에 일시 중지하는 추가 작업을 수행하여 작업에 관련된 각 변수 또는 데이터 구조의 기본 데이터 유형을 결정한다는 점에서 더 복잡합니다. Python은 프로그래머가 기본 데이터 유형의 관점에서 생각하지 못하게하고 작업을 더 높은 수준으로 표현할 수 있도록합니다. 이 자유의 가격은 성능입니다. "인터프리터 (interpreter)"는 데이터 유형을 검사하기 위해 일시 ​​정지해야하기 때문에 파이썬에서 선호하는 용어이며, 동적으로 타입이 지정된 언어의 비교적 간결한 구문이 대화 형 인터페이스에 적합하기 때문입니다. 대화식 Java 인터페이스를 구축하는 데 기술적 장벽은 없지만 정적 형식 코드를 대화식으로 작성하는 것은 지루한 일이므로 그렇게하지는 않습니다.

Java 세계에서 가상 머신은 실제로 머신 명령어로 컴파일 될 수있는 언어로 작성된 프로그램을 실행하기 때문에 쇼를 훔쳐 결과적으로 속도와 리소스 효율성이 향상됩니다. Java 바이트 코드는 Java 가상 머신에서 컴파일 된 프로그램의 성능에 비교적 근접한 성능으로 실행될 수 있습니다. 바이트 코드에 기본 데이터 형식 정보가 있기 때문입니다. Java 가상 머신은 Java를 자체 범주에 배치합니다.

이식 가능하고 정적 인 유형의 언어

다음으로 가장 가까운 것은 LLVM이지만 LLVM은 다른 수준에서 작동합니다.

휴대용 해석 언어

"바이트 코드"라는 용어는 Java와 Python 모두에서 사용되지만 모든 바이트 코드가 동일하게 생성되는 것은 아닙니다. 바이트 코드는 컴파일러 / 통역사가 사용하는 중간 언어의 일반적인 용어입니다. gcc와 같은 C 컴파일러조차도 중간 언어 (또는 여러 언어) 를 사용하여 작업을 완료합니다. Java 바이트 코드에는 기본 데이터 유형에 대한 정보가 포함되어 있지만 Python 바이트 코드에는 없습니다. 이와 관련하여 Python (및 Bash, Perl, Ruby 등) 가상 머신은 기본적으로 Java 가상 머신보다 느리거나 오히려 더 많은 작업이 필요합니다. 다른 바이트 코드 형식에 포함 된 정보를 고려하는 것이 유용합니다.

  • llvm : CPU 레지스터
  • Java : 기본 데이터 유형
  • 파이썬 : 사용자 정의 타입

실제 비유를 그리려면 : LLVM은 원자와 함께 작동하고, Java 가상 머신은 분자와, Python 가상 머신은 재료와 함께 작동합니다. 모든 것이 궁극적으로 아 원자 입자 (실제 기계 작동)로 분해되어야하기 때문에 Python 가상 기계는 가장 복잡한 작업을 수행합니다.

정적 타입 언어의 인터프리터 / 컴파일러에는 동적 타입 언어의 인터프리터 / 컴파일러와 동일한 수하물이 없습니다. 정적으로 유형이 지정된 언어의 프로그래머는 여유를 극복해야합니다. 그러나 모든 비 결정적 함수가 비밀리에 결정론적인 것처럼 동적으로 유형이 지정된 모든 언어는 비밀리에 정적으로 유형이 지정됩니다. 따라서 두 언어 제품군 간의 성능 차이는 Python이 HAL 9000으로 이름을 변경하는 시점에서 수평을 유지해야합니다.

파이썬과 같은 동적 언어의 가상 머신은 이상적인 논리 머신을 구현하며 실제 물리적 하드웨어와 반드시 긴밀하게 대응할 필요는 없습니다. 반면 Java 가상 머신은 기능을 일반 C 컴파일러와 비슷하지만 머신 명령어를 내보내는 대신 내장 루틴을 실행한다는 점이 다릅니다. 파이썬에서 정수는 많은 속성과 메소드가 첨부 된 파이썬 객체입니다. Java에서 int는 지정된 수의 비트 (일반적으로 32)입니다. 실제로는 공정한 비교가 아닙니다. 파이썬 정수는 실제로 Java Integer 클래스와 비교되어야합니다. Java의 "int"기본 데이터 유형은 Python 언어에이 기본 계층이 없기 때문에 Python 바이트 코드도 없기 때문에 Python 언어의 어떤 것과도 비교할 수 없습니다.

Java 변수가 명시 적으로 입력 되었기 때문에 Jython 성능 과 같은 것이 cPython 과 같은 구장에 있다고 합리적으로 기대할 수 있습니다 . 반면에, 파이썬으로 구현 된 Java 가상 머신은 진흙보다 느리게 보장됩니다. 루비, 펄 등이 더 나아질 것으로 기대하지 마십시오. 그들은 그렇게하도록 설계되지 않았습니다. 이들은 "스크립트"를 위해 설계되었으며, 이는 동적 언어로 프로그래밍하는 것입니다.

가상 머신에서 발생하는 모든 작업은 결국 실제 하드웨어에 충돌해야합니다. 가상 머신에는 논리 연산의 조합을 실행할 수있을 정도로 일반적으로 사전 컴파일 된 루틴이 있습니다. 가상 머신은 새로운 머신 명령어를 생성하지 않을 수도 있지만, 확실히 복잡한 루틴 시퀀스에서 자체 루틴을 반복해서 실행하고 있습니다. Java 가상 머신, Python 가상 머신 및 기타 모든 범용 가상 머신은 상상할 수있는 로직을 수행하도록 동축 될 수 있다는 의미에서 동일하지만 어떤 작업에 따라 다릅니다. 프로그래머가 맡은 작업과 수행해야 할 작업

Psyco for Python은 완전한 Python 가상 머신이 아니지만, 몇 줄의 코드를 컴파일 할 수 있다고 생각하는 시점에서 일반 Python 가상 머신을 하이재킹하는 JIT (just-in-time) 컴파일러입니다. 각 반복마다 값이 변경 되더라도 변수는 일정하게 유지됩니다. 이 경우 일반 가상 머신의 불필요한 유형 결정 중 일부를 포기할 수 있습니다. 그러나 Psyco의 발 아래에서 유형을 꺼내지 않도록 조심해야합니다. 그러나 Pysco는 일반적으로 유형이 변경되지 않을 것이라고 확신하지 못하는 경우 일반 가상 머신으로 대체하는 것을 알고 있습니다.

이야기의 교훈은 원시 데이터 유형 정보가 컴파일러 / 가상 머신에 실제로 도움이된다는 것입니다.

마지막으로, 모든 관점에서 살펴보면 이것을 고려하십시오 .iPhone에서 실행되는 qemu 가상 머신에서 실행되는 LLVM에서 실행되는 Java 인터프리터 / 가상 머신에서 실행되는 Java로 구현 된 Python 인터프리터 / 가상 머신에서 실행되는 Python 프로그램입니다.

퍼머 링크


1
trying to write any statically-typed code interactively would be tedious. OCaml과 Haskell을 알고 있다면 매우 간결한 정적 유형 언어 이므로 사실이 아님을 알 수 있습니다.
Matthias Braun

@MatthiasBraun이 기능적 언어가 간결한 코드를 생성하지만 반드시 대화 형 모드에 적합하다는 것을 의미하지는 않습니다. OCaml과 Haskell이 lisp와 같이 동적으로 유형이 지정되면 대화식 모드에서 더 잘 작동합니다.
폭탄

58

아마도 다른 용어에 대한 한 가지 이유는 일반적으로 파이썬 인터프리터 원시 인간 판독 가능 소스 코드를 제공하고 바이트 코드와 그 모든 것에 대해 걱정하지 않기 때문입니다.

Java에서는 명시 적으로 바이트 코드로 컴파일 한 다음 VM의 소스 코드가 아닌 바이트 코드 만 실행해야합니다.

비록 파이썬이 덮개 아래에서 가상 머신을 사용하더라도, 사용자 관점에서이 세부 사항을 대부분 무시할 수 있습니다.


1
나는 동의한다. 이러한 용어의 차이는 실제로 최종 사용자 (개발자, 즉) 경험에 달려 있습니다. 기술 라인이 존재하지 않을 정도로 엄청나게 희미 해 지므로 실제 기술적 차이와 아무런 관련이 없습니다.
Cody Brocious

1
+1 : 더 중요한 점은 무엇입니까? 이 차이로 인해 어떤 프로그램을 작성할 수 없습니까? 어떤 스택 트레이스 백이 혼란 스럽습니까? 어떤 라이브러리가 제대로 작동하지 않습니까?
S.Lott

@ S.Lott 동료들과 논쟁을 벌이는 것이 항상 좋기 때문입니다. ;)
Qix-MONICA가 MISTREATED

16

Interpreter 는 소스 코드를 효율적인 중간 표현 (코드)으로 변환하여 즉시 실행합니다.

Virtual Machine 은 인터프리터 시스템의 일부인 컴파일러로 빌드 된 저장된 사전 컴파일 된 코드를 명시 적으로 실행합니다.

가상 머신의 매우 중요한 특성은 내부에서 실행되는 소프트웨어가 가상 머신이 제공하는 리소스로 제한된다는 것입니다. 정확하게, 그것은 가상 세계에서 벗어날 수 없습니다. 원격 코드 인 Java 애플릿의 안전한 실행을 생각하십시오.

파이썬의 경우 ,이 게시물의 의견에서 언급했듯이 pyc 파일을 유지 하면 메커니즘이 VM과 같아 지고이 바이트 코드가 더 빠르게 실행됩니다. 이것은 여전히 ​​해석되지만 컴퓨터 친화적 인 형태로 해석됩니다 . 이것을 전체적으로 살펴보면 PVM은 Python Interpreter의 마지막 단계입니다.

결론은 파이썬 인터프리터를 언급 할 때, 우리가 그것을 전체적으로 참조한다는 것을 의미하고, PVM을 말할 때, 그것은 런타임 환경 인 파이썬 인터프리터의 일부에 대해서만 이야기하고 있다는 것을 의미합니다. Java와 유사하게 differentyl, JRE, JVM, JDK 등의 다른 부분을 참조합니다.

자세한 내용은 Wikipedia Entry : InterpreterVirtual Machine 입니다. 또 다른 하나 여기 . 여기서 응용 프로그램 가상 머신 비교를 찾을 수 있습니다 . 컴파일러, 인터프리터 및 VM의 차이점을 이해하는 데 도움이됩니다.


12

인터프리터라는 용어는 이전 쉘 스크립팅 언어로 거슬러 올라가는 레거시 용어입니다. "스크립팅 언어"가 완전한 기능을 갖춘 언어로 발전하고 해당 플랫폼이 더욱 정교 해지고 샌드 박스 화됨에 따라 가상 머신과 인터프리터 (Python 의미)의 차이는 매우 작거나 존재하지 않습니다.

파이썬 인터프리터는 별도의 컴파일 단계없이 실행될 수 있다는 점에서 쉘 스크립트와 동일한 방식으로 작동합니다. 그 외에도 Python의 인터프리터 (또는 Perl 또는 Ruby)와 Java의 가상 머신의 차이점은 대부분 구현 세부 사항입니다. (Java가 Python보다 샌드 박스가 더 완벽하다고 주장 할 수 있지만 궁극적으로는 네이티브 C 인터페이스를 통해 기본 아키텍처에 대한 액세스를 제공합니다.)


1
별도의 (사용자가 볼 수있는) 컴파일 단계없이 Java 코드를 실행할 수있는 Java 쉘이 있습니다.
Lie Ryan

1
gimme 이름 : D
Maciej Nowicki

11

" Java Virtual Machine을 선택해야하지만 Python 인터프리터 "라는 질문에 대한 심층 답변을 제공하기 위해 토론의 시작점과 관련하여 컴파일 이론 분야로 돌아가 보겠습니다.

일반적인 프로그램 컴파일 프로세스에는 다음 단계가 포함됩니다.

  1. 어휘 분석 . 프로그램 텍스트를 토큰 이라고하는 의미있는 "단어"로 분할합니다 (프로세스의 일부로 모든 주석, 공백, 줄 바꾸기 등은 프로그램 동작에 영향을주지 않기 때문에 제거됩니다). 결과는 순서가 지정된 토큰 스트림입니다.
  2. 구문 분석 . 토큰 스트림에서 소위 AST (Abstract Syntax Tree) 를 빌드합니다 . AST는 토큰 간의 관계를 설정하고 결과적으로 프로그램의 평가 순서를 정의합니다.
  3. 시맨틱 분석 . 프로그래밍 언어의 유형 및 일련의 의미 규칙에 대한 정보를 사용하여 AST의 의미 정확성을 검증합니다. (예를 들어, a = b + c구문 관점에서 올바른 문장이지만 a상수 객체로 선언 된 경우 의미 론적 관점에서는 완전히 올바르지 않습니다. )
  4. 중간 코드 생성 . AST를 기계적으로 독립적 인 "기본적인"작업의 선형 순서의 스트림으로 직렬화합니다. 실제로 코드 생성기는 AST를 통과하고 평가 단계의 순서를 기록합니다. 결과적으로 프로그램은 트리와 같은 표현으로 프로그램 평가 순서가 유지되는 훨씬 더 간단한 목록과 같은 표현을 얻습니다.
  5. 기계 코드 생성 . 머신 독립 "프리미티브"바이트 코드 형태의 프로그램은 특정 프로세서 아키텍처의 머신 코드로 변환됩니다.

확인. 이제 용어를 정의하겠습니다.

해당 단어의 고전적인 의미에서 통역사 는 프로그램 텍스트 에서 직접 생성 된 AST를 기반으로 한 프로그램 평가를 기반으로 실행을 가정 합니다 . 이 경우, 프로그램은 소스 코드 형태로 배포되고 인터프리터는 종종 동적으로 (상태 별 또는 라인 별) 프로그램 텍스트로 제공됩니다. 각 입력 명령문에 대해 인터프리터는 AST를 빌드하고 즉시 프로그램의 "상태"를 변경하여 평가합니다. 이것은 스크립팅 언어로 설명되는 일반적인 동작입니다. 예를 들어 Bash, Windows CMD 등을 고려하십시오. 개념적으로 Python도이 방식을 사용합니다.

인터프리터에서 중간 기계 독립적 이진 바이트 코드 단계 생성에서 AST 기반 실행 단계를 대체하면 프로그램 실행의 전체 프로세스를 컴파일과 실행의 두 단계로 나눕니다. 이 경우 이전에 인터프리터였던 것은 바이트 코드 컴파일러가되어 텍스트 형식에서 이진 형식 으로 프로그램을 변환합니다 . 그런 다음 프로그램은 이진 형태로 배포되지만 소스 코드 형태로는 배포되지 않습니다. 사용자 머신에서, 그 바이트 코드는 새로운 엔티티 인 가상 머신 으로 공급되는데 , 이는 실제로 그 바이트 코드를 해석합니다. 이로 인해 가상 머신을 바이트 코드 인터프리터 라고도 합니다. 그러나 여기에주의를 기울이십시오! 고전 통역사는텍스트 인터프리터 이지만 가상 머신은 이진 인터프리터입니다 ! 이것은 Java와 C #이 취하는 접근법입니다.

마지막으로 바이트 코드 컴파일러에 머신 코드 생성을 추가하면 클래식 컴파일러 라고 불리는 결과를 얻습니다 . 클래식 컴파일러는 프로그램 소스 코드를 특정 프로세서 의 기계 코드 로 변환합니다 . 그런 다음 해당 기계 코드는 추가 중개없이 텍스트 프로세서 나 2 진 인터프리터없이 모든 유형의 인터프리터없이 대상 프로세서에서 직접 실행될 수 있습니다 .

이제 원래 질문으로 돌아가서 Java 대 Python을 고려해 보겠습니다.

Java 는 처음에 가능한 한 적은 구현 종속성을 갖도록 설계되었습니다. 디자인은 "한 번만 쓰고 어디서나 실행"(WORA) 원칙을 기반으로합니다. 이를 구현하기 위해 Java 는 처음에 기계 독립적 인 이진 바이트 코드 로 컴파일되는 프로그래밍 언어로 설계되었으며, 다시 컴파일 할 필요없이 Java 를 지원하는 모든 플랫폼에서 실행될 수 있습니다 . WORA 기반 C ++ 과 같은 Java 에 대해 생각할 수 있습니다 . 실제로 JavaPython 과 같은 스크립팅 언어보다 C ++에 더 가깝습니다 . 그러나 달리 C ++ , 자바이진 바이트 코드 로 컴파일되도록 설계되었으며 가상 머신 환경에서 실행되는 반면 C ++ 는 머신 코드로 컴파일 된 다음 대상 프로세서에서 직접 실행되도록 설계되었습니다.

파이썬 은 처음에는 스크립트 ( 프로그래밍 언어 규칙에 따라 작성된 텍스트 형태의 프로그램)를 해석하는 일종의 스크립팅 프로그래밍 언어로 설계되었습니다 . 이로 인해 Python은 처음에 Bash 또는 Windows CMD와 같이 한 줄 명령 또는 명령문의 동적 해석을 지원했습니다. 같은 이유로 파이썬의 초기 구현에는 이러한 바이트 코드를 실행하기위한 모든 종류의 바이트 코드 컴파일러와 가상 머신이 없었지만, 처음부터 파이썬 에는 파이썬 프로그램 텍스트 를 이해하고 평가할 수있는 인터프리터 가 필요했습니다 .

이 때문에, 역사적으로, 자바 개발자에 대해 이야기하는 경향이 자바 가상 머신 (처음에 있기 때문에 자바 의 패키지로왔다 자바 바이트 코드 컴파일러와 바이트 코드 인터프리터 - JVM 등) 파이썬 개발자가 이야기하는 경향이 파이썬 처음에 있기 때문에 (통역 파이썬이 있다 어떤 가상 머신도 아니며 어떤 종류 의 이진 코드로의 컴파일이나 변환없이 프로그램 텍스트를 직접 실행 하는 일종의 고전적인 텍스트 인터프리터 였습니다.

현재 파이썬에는 가상 머신이 있으며 파이썬 바이트 코드를 컴파일하고 해석 할 수 있습니다. 그리고 그 사실은 혼란에 추가 투자를합니다. 왜 Java Virtual Machine이 아니라 Python 인터프리터입니까?그 프로그램은 정확히 동일한 행동을 보여주고 동일한 입력에서 동일한 출력을 생성합니다. 관찰 할 수있는 유일한 차이점은 프로그램 실행 속도와 인터프리터가 사용하는 메모리 양입니다. 따라서 파이썬의 가상 머신은 언어 설계에서 피할 수없는 부분이 아니라 주요 파이썬 인터프리터의 선택적 확장입니다.

자바도 비슷한 방식으로 고려 될 수 있습니다. Java는 JIT 컴파일러를 가지고 있으며 Java 클래스의 메소드를 대상 플랫폼의 기계 코드로 선택적으로 컴파일 한 다음 직접 실행할 수 있습니다. 그러나! Java는 여전히 바이트 코드 해석을 Java 프로그램 실행의 기본 방법으로 사용합니다. Java 가상 머신은 최적화 기술로서 독점적으로 가상 머신을 이용하는 Python 구현과 마찬가지로 최적화 목적으로 만 Just-In-Time 컴파일러를 사용합니다. 마찬가지로, 머신 코드의 직접 실행이 Java 바이트 코드의 해석보다 10 배 이상 빠르다는 사실 때문입니다. 그리고 파이썬의 경우와 마찬가지로 JVM의 핵심에 JIT 컴파일러가 존재한다는 것은 Java 언어 디자이너와 Java 프로그램 개발자 모두에게 절대적으로 투명합니다. JIT 컴파일러가 있거나없는 JVM에서 동일한 Java 프로그래밍 언어를 구현할 수 있습니다. 같은 방식으로 JIT가 있거나없는 JVM에서 동일한 프로그램을 실행할 수 있으며 동일한 프로그램은 정확히 동일한 동작을 보여주고 두 JVM의 동일한 입력에서 동일한 출력을 생성합니다 (JIT 유무에 관계없이). 그리고 파이썬의 경우와 마찬가지로, 유일하게 눈에 띄는 차이점은 실행 속도와 JVM이 소비하는 메모리 양에 있습니다. 마지막으로 Python의 경우와 마찬가지로 Java의 JIT도 언어 설계에서 피할 수없는 부분이 아니라 주요 JVM 구현의 선택적 확장입니다. 동일한 프로그램은 정확히 동일한 동작을 보여주고 두 JVM (JIT 유무에 관계없이)의 동일한 입력에서 동일한 출력을 생성합니다. 그리고 파이썬의 경우와 마찬가지로, 유일하게 눈에 띄는 차이점은 실행 속도와 JVM이 소비하는 메모리 양에 있습니다. 마지막으로 Python의 경우와 마찬가지로 Java의 JIT도 언어 설계에서 피할 수없는 부분이 아니라 주요 JVM 구현의 선택적 확장입니다. 동일한 프로그램은 정확히 동일한 동작을 보여주고 두 JVM (JIT 유무에 관계없이)의 동일한 입력에서 동일한 출력을 생성합니다. 그리고 파이썬의 경우와 마찬가지로, 유일하게 눈에 띄는 차이점은 실행 속도와 JVM이 소비하는 메모리 양에 있습니다. 마지막으로 Python의 경우와 마찬가지로 Java의 JIT도 언어 설계에서 피할 수없는 부분이 아니라 주요 JVM 구현의 선택적 확장입니다.

Java 및 Python 가상 머신의 설계 및 구현의 관점에서 볼 때, 가상 머신은 그대로 유지되는 반면 (주의!) JVM은 간단한 기본 조작과 높은 명령 디스패치 비용을 가진 저수준 가상 머신의 예입니다. 파이썬은 차례대로 명령이 복잡한 동작을 보여주고 명령 디스패치 비용이 그다지 중요하지 않은 고급 가상 머신입니다. Java는 매우 낮은 추상화 수준으로 작동합니다. JVM은 작고 잘 정의 된 기본 유형 세트에서 작동하며 바이트 코드 명령어와 기본 머신 코드 명령어간에 매우 밀접한 대응 관계 (일반적으로 일대일)를 갖습니다. 반대로 Python 가상 머신은 높은 추상화 수준에서 작동하며 복잡한 데이터 유형 (객체)으로 작동하며 임시 다형성을 지원합니다. 바이트 코드 명령어는 복잡한 동작을 나타내며 일련의 여러 네이티브 머신 코드 명령어로 표시 될 수 있습니다. 예를 들어, 파이썬은 무한 범위 수학을 지원합니다. 따라서 Python VM은 잠재적으로 큰 정수에 대한 긴 산술을 이용하여 연산 결과가 기계어를 오버플로 할 수 있습니다. 따라서, 파이썬에서 산술을위한 하나의 바이트 코드 명령어는 파이썬 VM 내부의 함수 호출에 노출 될 수 있지만, JVM에서는 산술 연산이 하나 또는 몇 개의 기본 머신 명령어로 표현 된 간단한 연산에 노출됩니다. 따라서 Python VM은 잠재적으로 큰 정수에 대한 긴 산술을 이용하여 연산 결과가 기계어를 오버플로 할 수 있습니다. 따라서, 파이썬에서 산술을위한 하나의 바이트 코드 명령어는 파이썬 VM 내부의 함수 호출에 노출 될 수 있지만, JVM에서는 산술 연산이 하나 또는 몇 개의 기본 머신 명령어로 표현 된 간단한 연산에 노출됩니다. 따라서 Python VM은 잠재적으로 큰 정수에 대한 긴 산술을 이용하여 연산 결과가 기계어를 오버플로 할 수 있습니다. 따라서, 파이썬에서 산술을위한 하나의 바이트 코드 명령어는 파이썬 VM 내부의 함수 호출에 노출 될 수 있지만, JVM에서는 산술 연산이 하나 또는 몇 개의 기본 머신 명령어로 표현 된 간단한 연산에 노출됩니다.

결과적으로 다음 결론을 도출 할 수 있습니다. Java Virtual Machine이지만 Python 인터프리터는 다음과 같은 이유로 인해 발생합니다.

  1. 가상 머신이라는 용어는 이진 바이트 코드 해석을 가정하고 인터프리터라는 용어는 프로그램 텍스트 해석을 가정합니다.
  2. 역사적으로 Java는 이진 바이트 코드 해석을 위해 설계 및 구현되었으며 Python은 처음에 프로그램 텍스트 해석을 위해 설계 및 구현되었습니다. 따라서 "Java Virtual Machine"이라는 용어는 Java 커뮤니티에서 역사적으로 잘 확립되어 있습니다. 마찬가지로 "Python Interpreter"라는 용어는 역사적으로 파이썬 커뮤니티에서 잘 확립되어 있습니다. 사람들은 전통을 연장하고 오래 전에 사용했던 것과 같은 용어를 사용하는 경향이 있습니다.
  3. 마지막으로 현재 Java의 경우 바이너리 바이트 코드 해석은 프로그램 실행의 기본 방법이며 JIT 컴파일은 선택적이고 투명한 최적화입니다. 그리고 파이썬의 경우 현재 프로그램 텍스트 해석은 파이썬 프로그램 실행의 주요 방법이며, 파이썬 VM 바이트 코드로 컴파일하는 것은 선택적이고 투명한 최적화입니다.

따라서 Java와 Python에는 가상 머신이 이진 바이트 코드 인터프리터가 있으므로 " Java Virtual Machine을 사용해야하는 이유는 무엇입니까?". 여기서 중요한 점은 파이썬의 경우 가상 머신은 프로그램 실행의 기본적이거나 필요한 수단이 아니라 고전적인 텍스트 인터프리터의 선택적 확장 일뿐입니다. 반면에 가상 머신은 불가피합니다. 프로그래밍 언어 설계를위한 정적 또는 동적 타이핑 선택은 주로 가상 머신 추상화 레벨에만 영향을 주지만 가상 머신이 필요한지 여부는 결정하지 않습니다. 두 타이핑 시스템을 사용하는 언어는 컴파일되도록 설계 될 수 있습니다 원하는 실행 모델에 따라 가상 머신의 환경 내에서 해석, 해석 또는 실행됩니다.


2
IMHO 공식 답변으로 선택해야합니다.
Ravikanth Andhavarapu

"자바와 파이썬 모두 가상 머신은 이진 바이트 코드 인터프리터이다." 기간.
stuartw

10

그들 사이에는 실질적인 차이가 없습니다. 사람들은 제작자가 선택한 컨벤션을 따릅니다.


3
아마 이것이 실제 답변이라고 생각하고 비트 부족으로 투표를 마쳤으므로 여기에 뼈를 던질 것입니다.
vikingben

3

파이썬에는 x86 용 JIT 컴파일러가있어 문제를 더욱 혼란스럽게한다는 것을 잊지 마십시오. (psyco 참조).

'해석 된 언어'에 대한보다 엄격한 해석은 예를 들어 Python과 비교하여 VM의 성능 문제를 논의 할 때만 유용하게됩니다. Ruby는 Python과 달리 해석 된 언어이기 때문에 느리게 간주되었습니다. 단어, 문맥이 전부입니다.


1
그건 틀렸어요. 첫째, "통역 된 언어"와 같은 것은 없습니다. 구현이 컴파일러 또는 인터프리터를 사용하는지 여부는 언어의 특성이 아니라 구현의 특성입니다. 둘째, 13 개 정도의 Ruby 구현 중 정확히 1 개는 인터프리터이며 다른 모든 것은 컴파일러가 있습니다.
Jörg W Mittag

2
셋째, 루비는 느리지 않습니다. 속도는 언어의 특성이 아니라 언어 구현이기 때문에 언어가 느리지 않습니다. 13 개 정도의 Ruby 구현 중 일부는 7 개의 Python 구현 중 일부보다 느리고 일부는 더 빠릅니다.
Jörg W Mittag

Jörg가 표준 구현을 비교하고 있다고 생각합니다. CPython과 Ruby (공식 구현의 이름은 Ruby라고합니다).
James McMahon

Arafangion은 "표준"구현을 참조 할 수도 있지만 그렇게해야합니다. 나는 Pythonista 해요하지만 난 싫어 어떤 내가 구현의 문제에 르그에 동의하기 때문에, 형태 "언어 X가 느리다"의 문을.
tzot

1
이것이 바로 내가 "(is?)", 특히 "느리게"라는 말의 이유입니다. 루비 자체가 느리다는 말은 어디에도 없었습니다.
Arafangion 2018

2

파이썬은 코드를 바이트 코드로 컴파일하지 않고 해석 할 수 있습니다 . 자바는 할 수 없다 .

파이썬은 컴파일 된 언어와 달리 해석되는 언어이지만 바이트 코드 컴파일러의 존재로 인해 구별이 모호해질 수 있습니다. 즉, 실행 파일을 명시 적으로 작성하지 않고 소스 파일을 직접 실행할 수 있습니다.

(문서에서).

자바에서, 모든 단일 파일을 하는 A를 컴파일 .class한 후 JVM에서 실행 파일. 반대로, 파이썬은 기본 스크립트에서 가져 오는 것을 수행하므로 해당 파일의 후속 사용 속도를 높일 수 있습니다.

그러나 일반적인 경우, 대부분의 파이썬 (적어도 CPython) 코드는 에뮬레이트 된 스택 머신에서 실행되는데,이 머신은 JVM의 명령어와 거의 동일한 명령어를 가지고 있으므로 큰 차이가 없습니다.

그러나이 사실에 대한 진정한 이유는 처음부터 자바가 "휴대용 실행 가능 바이트 코드"로 브랜드화되고 파이썬이 REPL을 사용하여 동적이고 해석 가능한 언어로 브랜드화 되었기 때문입니다. 이름 스틱!


0

우선, 프로그래밍이나 컴퓨터 과학은 일반적으로 수학이 아니며 우리가 자주 사용하는 대부분의 용어에 대한 엄격한 정의가 없습니다.

지금 당신의 질문에 :

통역사 란 무엇인가 (컴퓨터 과학에서)

가장 작은 실행 가능한 단위로 소스 코드를 번역 한 다음 해당 단위를 실행합니다.

가상 머신이란 무엇입니까

JVM의 경우 가상 머신은 인터프리터, 클래스 로더, 가비지 콜렉터, 스레드 스케줄러, JIT 컴파일러 및 기타 여러 가지를 포함하는 소프트웨어입니다.

보시다시피 인터프리터는 일부 또는 JVM이며 전체 JVM은 다른 많은 구성 요소를 포함하므로 인터프리터라고 할 수 없습니다.

파이썬에 대해 이야기 할 때 "통역사"라는 단어를 사용하는 이유

Java를 사용하면 컴파일 부분이 명시 적입니다. 반면에 파이썬은 컴파일 및 해석 프로세스에 대해 자바처럼 명시 적이 지 않습니다. 최종 사용자의 관점에서 해석은 파이썬 프로그램을 실행하는 데 사용되는 유일한 메커니즘입니다


0

아니요, 바이트 코드를 모두 해석하지는 않습니다.

파이썬은 pypy로 실행중인 경우에만 바이트 코드를 해석합니다. 그렇지 않으면 C로 컴파일되어 해당 수준에서 해석됩니다.

Java는 바이트 코드로 컴파일됩니다.


답변에 자원을 줄 수 있습니까?
Isuru Dilshan

그리고 이것은 자바에 있습니다 : en.wikipedia.org/wiki/Java_virtual_machine
Michael Tamillow

이것이 스택 오버플로의 문제입니다. 누군가가 불려지고 다운 보트로 표현하기 때문에 삐걱 거리는 사람이 있습니다.
Michael Tamillow

0

나는 둘 사이의 경계가 희미하다고 생각한다. 사람들은 대부분 "통역사"라는 단어의 의미와 언어가 "통역사 ... 컴파일러"스펙트럼의 각 측면에 얼마나 근접해 있는지에 대해 논쟁을 벌인다. 그러나 100 %는 없습니다. 스펙트럼의 가치가있는 Java 또는 Python 구현을 작성하는 것이 쉽다고 생각합니다.

현재 Java와 Python에는 가상 머신과 바이트 코드가 있지만 하나는 32 비트 정수와 같은 구체적인 값 크기로 작동하지만 다른 하나는 각 호출의 크기를 결정해야하지만 내 의견으로는 용어 사이의 경계를 정의하지 않습니다.

파이썬에 공식적으로 정의 된 바이트 코드가 없으며 메모리에만 존재한다는 주장은 파이썬 바이트 코드 만 인식하고 컴파일하는 부분은 브라우저 JS 시스템에서 수행 될 장치를 개발하려고하기 때문에 설득력이 없습니다.

성능은 구체적인 구현에 관한 것입니다. 우리는 객체의 크기를 알 필요가 없으며, 대부분의 경우 기본 유형이 아닌 구조로 작업합니다. 기존 계산 된 객체를 재사용하여 표현식 계산 중에 매번 새 객체를 만들 필요가 없도록 Python VM을 최적화 할 수 있습니다. 일단 완료되면 Java가 빛나는 곳에서 두 정수의 합을 계산하는 데 전역 성능 차이가 없습니다.

둘 사이에는 큰 차이가 없으며 일부 구현 뉘앙스와 최종 사용자와 관련이없는 최적화 부족 만 성능 저하가 눈에 띄기 시작하지만 아키텍처 문제가 아닌 구현입니다.


0

파이썬이 바이트 코드를 생성 할 필요가 없다고 언급 한 게시물의 경우 사실인지 확실하지 않습니다. 파이썬의 모든 호출 가능 객체 .__code__.co_code에는 바이트 코드가 포함 된 속성이 있어야합니다 . 컴파일 된 아티팩트가 저장되지 않을 수 있기 때문에 파이썬을 "컴파일되지 않음"이라고 부르는 의미있는 이유는 없습니다. 예를 들어 모든 이해력이 새로운 바이트 코드를 입력하도록 compile(mode='exec, ...)컴파일하는 compile(mode='single', ...)것과 같이 파이썬에서 디자인에 의해 저장되지 않는 경우가 있습니다. 이는 이해력 변수 범위가 파이썬 스크립트 실행과 pdb 사용과 같은 일관성 과 컴파일 사이에 일관성이없는 이유입니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.