[java] 컴파일 된 언어와 해석 된 언어

차이점을 더 잘 이해하려고합니다. 온라인에서 많은 설명을 찾았지만 실제적인 의미보다는 추상적 차이를 찾는 경향이 있습니다.

내 프로그래밍 경험의 대부분은 CPython (동적, 해석) 및 Java (정적, 컴파일)와 관련이 있습니다. 그러나 다른 종류의 해석되고 컴파일 된 언어가 있음을 이해합니다. 컴파일 된 언어로 작성된 프로그램에서 실행 파일을 배포 할 수 있다는 사실 외에도 각 유형마다 장점 / 단점이 있습니까? 종종, 사람들은 인터프리터 언어를 대화식으로 사용할 수 있다고 주장하는 사람들이 있지만 컴파일 된 언어도 인터랙티브 한 구현을 할 수 있다고 생각합니까?



답변

컴파일 된 언어는 프로그램이 일단 컴파일되면 대상 기계의 명령으로 표현되는 언어입니다. 예를 들어, 소스 코드의 “+”추가 작업은 머신 코드의 “ADD”명령으로 직접 변환 될 수 있습니다.

해석되는 언어는 명령이 대상 시스템에서 직접 실행되지 않고 다른 프로그램 (일반적 으로 네이티브 머신의 언어로 작성). 예를 들어, 동일한 “+”연산이 런타임에 인터프리터에 의해 인식되어 적절한 인수와 함께 자체 “add (a, b)”함수를 호출 한 다음 기계 코드 “ADD”명령을 실행합니다. .

컴파일 된 언어로 해석 된 언어로 수행 할 수있는 모든 작업을 수행 할 수 있으며 그 반대도 마찬가지입니다. 둘 다 튜링 완료입니다. 그러나 둘 다 구현 및 사용에 대한 장단점이 있습니다.

나는 완전히 일반화 할 것입니다 (순수 자 용서하십시오!), 대략 컴파일 언어의 장점은 다음과 같습니다.

  • 대상 머신의 고유 코드를 직접 사용하여 성능 향상
  • 컴파일 단계에서 매우 강력한 최적화를 적용 할 수있는 기회

해석 된 언어의 장점은 다음과 같습니다.

  • 구현하기 쉬움 (좋은 컴파일러 작성은 매우 어렵다!)
  • 컴파일 단계를 실행할 필요가 없습니다 : “즉석에서”직접 코드를 실행할 수 있습니다
  • 동적 언어에 더 편리 할 수 ​​있습니다

바이트 코드 컴파일과 같은 현대 기술은 약간의 복잡성을 추가합니다. 여기서 발생하는 것은 컴파일러가 기본 하드웨어와 동일하지 않은 “가상 머신”을 대상으로한다는 것입니다. 그런 다음이 가상 머신 명령어를 나중에 다시 컴파일하여 고유 코드를 얻을 수 있습니다 (예 : Java JVM JIT 컴파일러에서 수행 한대로).


답변

언어 자체는 컴파일되거나 해석되지 않으며 특정 언어 구현 만 있습니다. Java는 완벽한 예입니다. 바이트 코드 기반 플랫폼 (JVM), 네이티브 컴파일러 (gcj) 및 Java 수퍼 셋 (bsh)을위한 인터 포터가 있습니다. 이제 Java 란 무엇입니까? 바이트 코드 컴파일, 네이티브 컴파일 또는 해석?

컴파일 및 해석되는 다른 언어는 스칼라, 하스켈 또는 오캄입니다. 이러한 각 언어에는 대화식 인터프리터와 바이트 코드 또는 기본 기계 코드 컴파일러가 있습니다.

따라서 일반적으로 “컴파일 된”및 “통역 된”으로 언어를 분류하는 것은 의미가 없습니다.


답변

과거의 폭발 :

옛날 옛적에, 컴퓨팅 통역사와 컴파일러의 땅에 살았습니다. 모든 종류의 소란이 하나의 장점과 다른 하나 이상의 장점으로 이어졌습니다. 일반적인 의견 당시이 의 라인을 따라 뭔가했다 :

  • 통역사 : 빠른 개발 (편집 및 실행). 각 명령문은 실행될 때마다 머신 코드로 해석되어야하므로 실행 속도가 느립니다 (루프가 수천 번 실행 된 의미를 생각하십시오).
  • 컴파일러 : 개발 속도가 느립니다 (편집, 컴파일, 링크 및 실행. 컴파일 / 링크 단계에는 시간이 오래 걸릴 수 있음). 실행이 빠릅니다. 전체 프로그램은 이미 네이티브 머신 코드에있었습니다.

해석 된 프로그램과 컴파일 된 프로그램 간에는 런타임 성능에서 1 ~ 2 배의 차이가있었습니다. 예를 들어 코드의 런타임 변경 가능성과 같은 다른 구별 포인트도 관심의 대상이되었지만 런타임 성능 문제와 관련하여 큰 차이가있었습니다.

오늘날의 환경은 컴파일 / 통역 된 구별이 거의 관련이없는 정도로 발전했습니다. 많은 컴파일 된 언어는 완전히 기계 코드 기반이 아닌 런타임 서비스를 요구합니다. 또한 대부분의 해석 언어는 실행 전에 바이트 코드로 “컴파일”됩니다. 바이트 코드 인터프리터는 매우 효율적이며 실행 속도 관점에서 일부 컴파일러 생성 코드와 경쟁 할 수 있습니다.

고전적인 차이점은 컴파일러가 네이티브 머신 코드를 생성하고 인터프리터가 일종의 런타임 시스템을 사용하여 소스 코드를 읽고 머신 코드를 즉시 생성한다는 것입니다. 오늘날에는 고전적인 인터프리터가 거의 남아 있지 않습니다. 거의 모든 인터프리터가 바이트 코드 (또는 다른 반 컴파일 된 상태)로 컴파일 된 다음 가상 “머신”에서 실행됩니다.


답변

극단적이고 간단한 경우 :

  • 컴파일러는 대상 컴퓨터의 기본 실행 파일 형식으로 이진 실행 파일을 생성합니다. 이 바이너리 파일에는 시스템 라이브러리를 제외한 모든 필수 리소스가 포함되어 있습니다. 추가 준비 및 처리없이 실행할 수 있으며 코드는 대상 시스템에서 CPU의 기본 코드이므로 번개처럼 실행됩니다.

  • 인터프리터는 문장이나 코드를 입력 할 수있는 루프에 프롬프트를 사용자에게 제공하며, 적중 RUN또는 이에 상응하는 경우 인터프리터는 프로그램이 중지 점 또는 오류까지 실행될 때까지 각 라인을 검사, 스캔, 구문 분석 및 해석 적으로 실행합니다. . 각 줄은 자체적으로 처리되며 인터프리터는 이전에 본 줄을 “배우지”않습니다. 사람이 읽을 수있는 언어를 기계 명령으로 변환하려는 노력은 모든 줄에 대해 매번 발생하므로 개가 느립니다. 밝은면에서 사용자는 변수 변경, 코드 변경, 추적 또는 디버그 모드에서 실행 등 무엇이든 모든 방법으로 프로그램을 검사하고 상호 작용할 수 있습니다.

그 길을 벗어난 사람들과 함께, 인생은 더 이상 간단하지 않다는 것을 설명하겠습니다. 예를 들어

  • 많은 통역사가 주어진 코드를 미리 컴파일하여 번역 단계를 반복 할 필요가 없습니다.
  • 일부 컴파일러는 CPU 관련 머신 명령어가 아니라 가상 머신을위한 일종의 인공 머신 코드 인 바이트 코드로 컴파일합니다. 이렇게하면 컴파일 된 프로그램이 좀 더 이식성이 좋아 지지만 모든 대상 시스템에서 바이트 코드 인터프리터가 필요합니다.
  • 바이트 코드 인터프리터 (여기서는 Java를보고 있습니다)는 최근 실행 직전에 대상 섹션의 CPU에 대해 얻는 바이트 코드 (JIT라고 함)를 다시 컴파일하는 경향이 있습니다. 시간을 절약하기 위해 자주 실행되는 코드 (핫스팟)에 대해서만 수행됩니다.
  • 인터프리터처럼 보이고 작동하는 일부 시스템 (예 : Clojure)은 코드를 즉시 컴파일하지만 프로그램 환경에 대화식으로 액세스 할 수 있습니다. 그것은 기본적으로 바이너리 컴파일 속도가 빠른 통역사의 편의입니다.
  • 일부 컴파일러는 실제로 컴파일하지 않고 코드를 미리 소화하고 압축합니다. 나는 펄이 작동하는 방식을 잠시 들었다. 때로는 컴파일러가 약간의 작업을하고 있으며 대부분 여전히 해석 중입니다.

결국, 요즘 해석과 컴파일은 시간이 많이 걸리는 (일회) 컴파일 시간이 더 나은 런타임 성능으로 보상되지만 해석 환경은 상호 작용에 더 많은 기회를 제공한다는 점에서 트레이드 오프입니다. 컴파일과 해석은 프로그램을 “이해하는”작업이 여러 프로세스간에 어떻게 분리되어 있는지에 관한 문제이며, 요즘 언어와 제품이 두 세계의 최고를 제공하려고 시도함에 따라 그 선은 약간 모호합니다.


답변

에서 http://www.quora.com/What-is-the-difference-between-compiled-and-interpreted-programming-languages

“컴파일 된 프로그래밍 언어”및 “해석 된 프로그래밍 언어”는 의미가없는 개념이므로 차이는 없습니다. 모든 프로그래밍 언어는 무엇이든 해석하거나 컴파일 할 수 있습니다. 따라서 해석과 컴파일은 언어의 속성이 아닌 구현 기술입니다.

해석은 다른 프로그램 인 통역사가 해석을 위해 프로그램을 대신하여 작업을 수행하는 기술입니다. 프로그램을 읽고 단계별로 수행하는 것을 수행한다고 상상할 수 있다면, 스크래치 종이에 말하십시오. 그것은 통역사도 마찬가지입니다. 프로그램을 해석하는 일반적인 이유는 통역사가 상대적으로 작성하기 쉽다는 것입니다. 또 다른 이유는 인터프리터가 프로그램이 실행될 때 수행하려는 작업을 모니터링하여 정책 (예 : 보안)을 시행 할 수 있기 때문입니다.

컴파일은 한 언어로 작성된 프로그램 ( “원본 언어”)을 다른 언어 ( “객체 언어”)로 프로그램으로 변환하는 기술로, 원래 프로그램과 동일한 의미를 갖습니다. 번역을 수행하는 동안 컴파일러는 객체 프로그램의 의미를 변경하지 않고도 객체 프로그램을 더 빠르게 만드는 방식으로 프로그램을 변환하려고 시도하는 것이 일반적입니다. 프로그램을 컴파일하는 일반적인 이유는 소스 언어를 해석하는 오버 헤드없이 오브젝트 언어로 프로그램을 빠르게 실행할 수있는 좋은 방법이 있기 때문입니다.

위의 정의에 따라이 두 가지 구현 기술은 상호 배타적이지 않으며 보완적일 수도 있습니다. 전통적으로 컴파일러의 객체 언어는 머신 코드 또는 이와 유사한 것으로 특정 컴퓨터 CPU가 이해하는 많은 프로그래밍 언어를 나타냅니다. 그런 다음 기계 코드는 “금속에서”실행됩니다 (물론 충분히 살펴보면 “금속”이 통역사처럼 작동한다는 것을 알 수 있습니다). 그러나 오늘날 컴파일러가 해석해야 할 객체 코드를 생성하는 것은 매우 일반적입니다. 예를 들어, Java가 익숙하고 때로는 작동하는 방식입니다. 다른 언어를 자바 스크립트로 번역하는 컴파일러가 있는데, 종종 자바 스크립트를 해석 할 수있는 웹 브라우저에서 실행되며, 또는 가상 머신 또는 원시 코드를 컴파일하십시오. 또한 기계 코드에 대한 인터프리터가 있으며, 이는 한 종류의 하드웨어를 다른 종류의 에뮬레이션하는 데 사용할 수 있습니다. 또는 컴파일러를 사용하여 객체 코드를 생성 한 다음 다른 컴파일러의 소스 코드를 생성 할 수 있습니다.이 코드는 실행 시간에 맞춰 메모리에서 코드를 컴파일 할 수도 있습니다. . . 당신은 아이디어를 얻는다. 이러한 개념을 결합하는 방법에는 여러 가지가 있습니다.


답변

컴파일 된 소스 코드보다 해석 된 소스 코드의 가장 큰 장점은 PORTABILITY 입니다.

소스 코드가 컴파일 된 경우 프로그램을 실행하려는 각 유형의 프로세서 및 / 또는 플랫폼에 대해 다른 실행 파일을 컴파일해야합니다 (예 : Windows x86 용, Windows x64 용, Linux x64 용 등). 의 위에). 또한 코드가 완전히 표준을 준수하고 플랫폼 별 기능 / 라이브러리를 사용하지 않는 한 실제로 여러 코드 기반을 작성하고 유지해야합니다!

소스 코드가 해석되면 한 번만 작성하면 모든 플랫폼의 해당 통역사가 해석하고 실행할 수 있습니다! 그것은이다 휴대용 ! 통역 자체가 실행 가능한 프로그램입니다 참고 되는 특정 플랫폼 용으로 작성 및 컴파일.

컴파일 된 코드의 장점은 사람이 읽을 수있는 원본 소스 코드를 배포하는 대신 모호한 이진 실행 파일을 배포하기 때문에 최종 사용자 ( 지적 속성 일 수 있음)에서 소스 코드숨기는 것입니다.


답변

컴파일러와 인터프리터는 동일한 작업을 수행합니다. 프로그래밍 언어를 다른 pgoramming 언어 (일반적으로 하드웨어에 더 가깝고 종종 직접 실행 가능한 기계 코드)로 변환합니다.

전통적으로 “컴파일 된”은이 변환이 한 번에 발생하고 개발자가 수행하며 결과 실행 파일이 사용자에게 배포됨을 의미합니다. 순수한 예 : C ++. 컴파일은 일반적으로 시간이 오래 걸리고 결과 실행 파일이 더 빨리 실행되도록 많은 고가의 최적화를 시도합니다. 최종 사용자에게는 자체 컴파일 도구와 지식이 없으며 실행 파일은 종종 다양한 하드웨어에서 실행되어야하므로 하드웨어 별 최적화를 많이 수행 할 수 없습니다. 개발 중 별도의 컴파일 단계는 피드백주기가 길다는 것을 의미합니다.

일반적으로 “통역 됨”은 사용자가 프로그램을 실행하려고 할 때 번역이 “즉석에서”발생한다는 것을 의미합니다. 순수한 예 : 바닐라 PHP. 순진한 인터프리터는 실행될 때마다 모든 코드를 구문 분석하고 번역해야하므로 속도가 매우 느려집니다. 복잡하고 비용이 많이 드는 최적화를 수행 할 수 없습니다. 실행 시간이 오래 걸리기 때문입니다. 그러나 실행되는 하드웨어의 기능을 완전히 사용할 수 있습니다. 별도의 컴파일 단계가 없기 때문에 개발 중 피드백 시간이 줄어 듭니다.

그러나 오늘날 “컴파일 vs. 해석”은 흑백 문제가 아니며 그 사이에 음영이 있습니다. 순진하고 간단한 통역사는 거의 멸종되었습니다. 많은 언어가 2 단계 프로세스를 사용하여 고급 코드가 플랫폼 독립적 인 바이트 코드로 변환됩니다 (해석 속도가 훨씬 빠름). 그런 다음 프로그램 실행 당 최대 한 번 코드를 컴파일하고 때로는 결과를 캐시하고 드물게 실행되는 코드를 지능적으로 해석하고 많이 실행되는 코드에 대해 강력한 최적화를 수행하는 “정시 컴파일러”가 있습니다. 개발 중에 디버거는 전통적으로 컴파일 된 언어의 경우에도 실행중인 프로그램 내에서 코드를 전환 할 수 있습니다.