컴파일 된 언어보다 해석 된 언어를 사용하는 예는 무엇입니까?


11

해석 된 언어와 컴파일 된 언어의 차이점을 이해하지만 누군가가 컴파일 된 언어보다 해석 된 언어를 사용할 가능성이 높은 상황과 해석 된 언어보다 컴파일 된 언어를 사용할 가능성이있는 상황의 예를 제공 할 수 있다면 정말 도움이 되십시오.

답변:


11

해석 된 "언어"또는 컴파일 된 "언어"와 같은 것은 없습니다.

언어는 코드 키워드, 흐름 구조 및 기타 여러 가지 구문과 의미를 지정하지만 언어 사양에서 컴파일하거나 해석 해야하는지 여부를 지정하는 언어는 없습니다.

이제 언어 컴파일러와 언어 인터프리터를 사용할 때 의문의 여지가 있다면 실제로 컴파일러의 장점과 단점 대 해석기와 프로젝트의 목적에 달려 있습니다.

예를 들어, MRI ruby ​​인터프리터 대신 Java 라이브러리와 쉽게 통합하기 위해 JRuby 컴파일러를 사용할 수 있습니다. JRuby보다 MRI 루비 인터프리터를 사용해야하는 이유도 있지만, 나는 언어에 익숙하지 않아서 말할 수 없습니다.

통역사의 혜택 :

  • 컴파일이 없으면 코드 편집에서 앱 테스트까지의 시간이 단축 될 수 있습니다.
  • 인터프리터가 아키텍처 추상화를 관리하기 때문에 여러 아키텍처에 대해 바이너리를 생성 필요가 없습니다 (이진 배포가 아니라 정수 크기를 올바르게 처리하는 스크립트에 대해 여전히 걱정해야 할 수도 있음)

컴파일러의 장점 :

  • 컴파일 된 네이티브 코드에는 인터프리터의 오버 헤드가 없으므로 일반적으로 시간과 공간에서 더 효율적입니다
  • 상호 운용성은 일반적으로 더 좋습니다. 스크립트와의 진행 중 상호 운용을위한 유일한 방법은 표준 FFI가 아닌 인터프리터를 이용하는 것입니다.
  • 인터프리터가 컴파일되지 않은 아키텍처를 지원하는 기능 (예 : 임베디드 시스템)

그러나 90 %의 경우에는 다음과 같이 진행됩니다. 이 소프트웨어를 잘 알고 잘 작동하기 때문에이 소프트웨어를 blub에 작성하고 싶습니다. blub 인터프리터 (또는 컴파일러)는 blub에서 소프트웨어를 작성하는 데 일반적으로 인정되는 표준 방법이므로 사용합니다.

따라서 TL; DR 은 기본적으로 경우에 따라 특정 유스 케이스에 대한 인터프리터와 컴파일러의 비교입니다.

또한 FFI : Foreign Function Interface, 즉 다른 언어와의 상호 운용을위한 인터페이스입니다. Wikipedia 에서 더 읽기


2
내가 아는 한, UNIX 용 ksh와 같은 OS 용 스크립트 언어는 컴파일 할 수 없습니다.
NoChance

@delnan, 내 요점은 내가 알고있는 상용 또는 무료 소프트웨어를 통해 컴파일 할 수 없으며 기술적 이유로 인해 컴파일 할 수 없다는 것입니다.
NoChance

3
@EmmadKareem "컴파일 할 수 없습니다"와 같은 것은 없습니다. 언어 Li로 프로그램을 읽고 언어 La로 동등한 프로그램을 출력하는 프로그램을 작성합니다. 그것은 컴파일러입니다. 나는 실제로 청어 청어이기 때문에 튜링 완전성 인수를 불러내는 것을 주저하지만 각 프로그램은 궁극적으로 일련의 기계 코드 명령으로 바뀝니다. 다른 모든 방법이 실패하면 인터프리터 루프를 풀고 결과 코드를 단순화하여 더 이상 필요하지 않은 부분을 제거하십시오. 인터프리터가 인터프리터없이 언어로 작성된 경우 컴파일러로 무언가를 칠 때까지 반복하십시오.

1
(나는 그것을 더 잘 표현하기 위해 내 의견을 수정했지만 분명히 너무 늦게 행동했다.) @EmmadKareem 네, 분명히 일부 언어는 컴파일러를 통해 구현되지 않았습니다. 그러나 이것이 어떻게 관련되는지 알 수 없습니다. 항상 가능하고 가능하며 언제든지 노력할 수 있습니다. 이것은 요점의 결과입니다. 즉 언어는 본질적으로 컴파일되거나 해석되지 않으며 두 가지 방식으로 구현 될 수 있습니다. 그리고 무수히 다른 방식으로 (잘 말해서, 약간의 변형과 리믹스).

2
@EmmadKareem 원한다면 ksh 언어 사양을 사용하여이를 읽고 기본 바이너리를 생성하는 컴파일러를 작성할 수 있습니다. 컴파일되거나 해석되는 언어는 언어 정의에 있지 않습니다.
Jimmy Hoffa

8

여기서 중요한 점은 많은 언어 구현이 실제로 두 가지를 혼합 한 것입니다. 오늘날 일반적으로 사용되는 많은 언어는 프로그램을 바이트 코드와 같은 중간 형식으로 컴파일 한 다음 인터프리터에서 실행하여 작동합니다. Java, C #, Python, Ruby 및 Lua가 일반적으로 구현되는 방식입니다. 실제로 오늘날 사용되는 대부분의 언어가 어떻게 구현되는지는 의심 할 여지가 없습니다. 사실 오늘날 언어는 코드를 해석하고 컴파일합니다. 이러한 언어 중 일부에는 추가 JIT 컴파일러가있어 실행을 위해 바이트 코드를 기본 코드로 변환합니다.

제 생각에는 해석 및 컴파일 된 언어는 더 이상 오늘날의 언어 구현의 복잡성을 구별하는 데 유용한 범주가 아니기 때문에 그만 두어야합니다.

해석되고 컴파일 된 언어의 장점에 대해 물어 보면 아마도 다른 의미 일 것입니다. 정적 / 동적 타이핑의 장점, 네이티브 실행 파일 배포의 장점, JIT 및 AOT 컴파일의 상대적 이점에 대해 문의 할 수 있습니다. 이것들은 모두 해석 / 컴파일과 관련이 있지만 다른 문제입니다.


2

우선, 프로그래밍 언어를 해석하고 컴파일 할 수 있습니다. 해석과 컴파일은 소스 코드에서 실행 코드를 생성하는 방법 일뿐입니다. 인터프리터를 사용하면 소스 코드가 인터프리터에 의해 읽혀지고 해석 되어 해석 할 때 코드가 실행됩니다. 반면에 컴파일러는 소스 코드를 읽고 소스 코드에서 실행 가능한 이진 파일을 생성하므로 프로그램을 별도의 프로세스로 독립적으로 실행할 수 있습니다.

누구나 궁금해하기 전에 ... 예, C / C ++ / C # / Java를 해석 할 수 있으며, JavaScript와 Bash 스크립트를 컴파일 할 수 있습니다. 이러한 언어에 대한 통역사 또는 컴파일러가 있는지 여부는 또 다른 질문입니다.

이제 "컴파일 된 언어"대신 "해석 된 언어"를 사용할 때 실제로 질문에 대답합니다. 질문 자체는 다소 혼란 스럽지만 컴파일보다 해석을 선호하는 시점을 의미한다고 가정합니다. 컴파일의 단점 중 하나는 컴파일 프로세스로 인해 오버 헤드가 발생한다는 것입니다. 소스 코드는 실행 가능한 머신 코드로 컴파일되어야하므로 프로그램을 실행하기 위해 소스 코드 를 호출 할 때 최소한의 지연이 필요한 작업에는 적합하지 않습니다 . 반면에 컴파일 된 소스 코드는 코드 해석으로 인한 오버 헤드로 인해 동등한 해석 소스 코드 보다 거의 항상 빠릅니다 . 반면에 통역사는 소스 코드를 호출하고 실행할 수 있습니다 호출 오버 헤드가 거의 없지만 런타임 성능이 저하됩니다.

결국, 서로를 선호 할 때 명확한 유스 케이스 를 언급하는 것은 거의 불가능 하지만, 예를 들어 (내 비현실적으로 비현실적 인) 사례는 프로그램 소스 코드가 프로그램 호출간에 동적으로 변경되고 컴파일 오버 헤드가 너무 클 때입니다 실행 가능한 선택이 되려면 이 경우 컴파일하는 대신 소스 코드를 해석하는 것이 바람직 할 것입니다.

그러나, 거기에 뭔가 배포시 hidnig 소스 코드 : 실제 예를 볼 수있다. 기본적으로컴파일 된 코드 개발자는 프로그램 및 데이터의 실행 가능한 Macine 코드를 배포합니다. 해석 된 코드를 사용하면 소스 코드 자체를 배포해야합니다.이 코드는 네이티브 머신 코드를 리버스 엔지니어링하는 것보다 훨씬 적은 노력으로 검사하고 리버스 엔지니어링 할 수 있습니다. 이에 대한 한 가지 예외는 C # 및 Java와 같은 언어로 즉석 언어 / 바이트 코드 (C #의 경우 MSIL 및 Java의 경우 Java 바이트 코드)로 컴파일 된 다음 런타임시 "적시에"배포되고 컴파일되는 언어입니다. 그러나 원본 소스 코드를 비교적 정확하게 재구성 할 수있는 MSIL 및 Java Bytecode 용 디 컴파일러가 있으며 이러한 리버스 엔지니어링은 네이티브 머신 코드에 배포 된 리버스 엔지니어링 제품보다 훨씬 사소합니다.


1
당신은 좋은 점을 지적하지만, 나는 교육자이기 때문에, 나는 몇 가지 구절 (두 번째 단락을 참조)에 대해 문제를 겪습니다. 1. 통역사가 컴파일하지 않습니다. 2. 최적화되지 않은 (예를 들어 바이트 코드 기반) 인터프리터가 나쁜 비 최적화 컴파일러를 이길 수있는 것은 (이러한 조건은 드물지만) 마음에들 수 있습니다. 인터프리터에서 JIT 컴파일러를 셀 수 있다면 이중으로 진행됩니다 (필자는하지 않지만 일부 사람들은 그렇게합니다).

@delnan 어쩌면 나는 영어를 모국어로 사용하지 않습니다. 그러나 세 번째 단락에 말할 수있는 한 통역사가 컴파일 할 것을 암시하지는 않습니다. 두 번째 요점으로, 컴파일 된 코드와 해석 된 코드의 유사성에 중점을 둔 동등한 단어 를 강조하여 컴파일러와 성능이 좋지 않은 컴파일러의 경우를 배제했습니다. 어쩌면 명확하지 않았지만 볼 수는 없습니다. 컴파일 또는
반복

죄송합니다. 첫 번째 요점을 신경 쓰지 마십시오. Mea Culpa. 두 번째 요점은 : "동등한"을 사용하여 해석되거나 컴파일 된 코드를 언급했습니다 (컴파일러와 인터프리터를 비교하는 것은 근본적으로 다른 일을하기 때문에 의미가 없습니다). 나는 내 예와 같이 엉뚱한 사례를 자세히 설명하는 데 시간을 낭비하지는 않을 것이라고 생각하지만, 그것이 항상 더 빠를 있는지 를 설명하는 문구에 찬성하여 "항상"을 삭제하는 것을 선호 합니다. 정의 된 IMHO] 및 런타임 전에 최적화를 수행 할 수있는 기회입니다.

1

통역 언어를 사용할 때 다음 시나리오를 생각할 수 있습니다.

  • 어떤 컴파일러는 리눅스 / 유닉스처럼, 존재하지 않는 경우 쉘 스크립트 .
  • 약간의 문제를 해결하는 빠르고 더러운 스크립트
  • 동적 HTML 페이지를 쉽게 작성하고 일반적으로 JSP (Tomcat이이를 실행하기 위해 서 블러로 컴파일), PHP, ASP 등으로 해석되는 언어

코드컴파일 하려는 경우 다음 시나리오를 생각할 수 있습니다 .

  • 앱이 비공개 소스이고 소스 코드를 제공하지 않기 때문에 바이너리배포 해야합니다 .
  • 임베디드 시스템 과 같은 속도 .
  • 엄격하게 형식화 된 언어를 가진 컴파일러 만 제공 할 수 있는 수준의 코드 형식 안전성 이 필요 합니다. 컴파일러는 소스 코드의 구석 구석마다 오타를 노출시키는 반면, 해석 된 프로그램에서는 오타가 프로덕션 코드로 발견되지 않을 수 있습니다.
  • 크고 복잡한 시스템 : OS 또는 사무실이 컴파일 된 바이너리 이외의 것으로 생각할 수 없습니다.
  • 모든 작은 오버 헤드를 방해하고 어셈블러 스 니펫 (모든 런타임, 특히 인터프리터와 어려움)과의 원활한 의사 소통이 필요합니다 (이 점은 @delnam comment에 의해 발생합니다)

3
언어 통역사는 언어를 더 강력하게 입력하지 않습니다. Haskell은 매우 강력하게 입력되었으며 GHCI를 사용하여 효과적으로 해석 할 수 있습니다. 강력하고 약한 타이핑은 언어의 측면이며 컴파일러 나 인터프리터의 측면은 아닙니다.
Jimmy Hoffa

1
-1 컴파일 전문가 : (1) 컴파일 코드는 리버스 엔지니어링을 방지하지 않으며 약간 어려워집니다. (2) 컴파일 (인터프리터 오버 헤드 제거, 응용 프로그램 코드의 자동 최적화)은 성능의 한 원천 일 뿐이며 전문가가 직접 수행하는 대규모 최적화보다 뛰어납니다. (3) 형식 검사는 일반적으로 컴파일과 결합되어 있지만 독립적입니다. 유형 검사기는 정적 분석 단계입니다. 코드를 내 보내지 않고 코드를 해석하기 전에 발생할 수 있습니다. (4) 매우 의심스러운 것 같습니다. 당신은 "상상할 수 없다"? 왜? 어떻게 필요합니까?

1
다른 해석 언어는 다른 프로그램에 통역사가있을 때마다 존재합니다. 인터프리터 패턴을 사용할 때마다 약간의 복잡한 해석 된 언어가 있습니다.

3
"스크립트"가 반드시 해석되는 것은 아닙니다. 많은 "스크립트"언어는 가상 머신의 바이트 코드 로 컴파일 된 다음 실행됩니다 (루아, 펄, 파이썬, 루비 참조). 컴파일이 발생할 때를 제외하고는 이것과 Java 사이에는 실질적인 차이가 없습니다.

3
+1, 이것이 OP가 실제로 추구 한 일종의 답변이라고 생각합니다. 지적한대로 포인트가 100 % 사실이 아닐 수도 있지만 실제적으로 고려해야 할 사항은 최소한 95 %입니다.
Doc Brown

1

결국, 생산성 (몇 줄의 코드를 작성해야하는지)과 성능 (프로그램이 얼마나 빨리 실행되는지) 사이의 큰 절충점이 있습니다.

때문에 언어를 해석 자세한 정보를 CPU 정보로 변환 할 때, 그들은 신뢰할 수있는 반사 및 동적 타이핑 크게 생산성을 향상 . 인터프리터 언어의 또 다른 장점은 플랫폼에 대한 인터프리터가있는 한 플랫폼에 독립적입니다.

CPU는 기계 코드에서 언어 코드를 변환하지 말고 코드를 동시에 실행하지 않아야하기 때문에 해석 된 경우와 같이 컴파일 된 언어가 더 빠른 프로그램을 생성합니다. 또한 컴파일 된 언어로 작성된 시스템 은 컴파일 타임에 문제를 감지 할 수 있기 때문에 더 안전 합니다. 기본적으로 실제로 프로그램을 실행할 때만 보는 대신 오류볼 수 있습니다 (현대 IDE로) 논리적 오류는 해결되지 않습니다).

이것을 알고, 해석되는 언어는 다음에 적합합니다.

  1. 생산적인 개발 : 빠른 웹 개발 (PHP, Javascript) 또는 프로토 타이핑.
  2. 교차 플랫폼; 예를 들어 JavaScript는 모든 브라우저 (모바일 브라우저 포함)에서 지원됩니다.

컴파일 된 언어는 다음과 같은 경우에 적합합니다.

  1. 성능이 중요하거나 (운영 체제) 리소스가 부족합니다 (마이크로 컨트롤러).
  2. 구축 할 시스템은 복잡합니다. 큰 시스템 (엔터프라이즈 시스템)을 빌드 할 때 컴파일 된 언어는 해석 가능한 언어로 나타날 수있는 많은 가능한 버그를 처리하는 데 필수적입니다. 또한 복잡한 프로그램에는 많은 자원이 필요하며 균형은 언어를 컴파일하는 경향이 있습니다.

해석 된 모든 언어가 동적으로 형식화되고 컴파일 된 모든 언어가 정적으로 형식화됨을 의미하기 때문에 -1은 완전히 사실이 아닙니다.
Daniel Pryden

@DanielPryden 그렇다면 거의 모든 해석 언어가 동적으로 입력되고 컴파일 된 언어가 정적으로 입력된다는 사실은 순수한 우연의 일치 여야합니다. 동적 유형 모델이 해석 된 언어에 적합하다는 것이 우연의 일치입니까?
m3th0dman

여러 가지 이유로 상관 관계가 있지만 필수 사항은 아닙니다. 이것은 실제로 StackOverflow에서 요청되었습니다. 왜 컴파일 된 언어가 강력한 타이핑을하면서 컴파일 된 동안 주로 오리 타입입니까?
Daniel Pryden

1
Erlang은 컴파일되고 동적으로 입력됩니다. Haskell은 정적으로 타이핑되어 컴파일되거나 해석 될 수 있습니다
Zachary K

1
@ZacharyK Erlang에는 런타임 시스템이 있습니다. Haskell은 대부분의 경우에 작성됩니다 (프로그램 작성).
m3th0dman

1

다른 사람들이 언급 한 이유 외에도, 어떤 형태의 편집이나 하이브리드 접근법에 대한 임시 해석을 선택하는 데 특히 중요한 사용 사례가 있습니다.

프로그래밍 언어가 통신 프로토콜 로 사용되는 경우 응답 대기 시간이 중요한 경우 컴파일 및 가능한 사전 처리에 시간을 낭비하지 않는 것이 좋습니다.

예를 들어 상담원 언어 또는 Tcl / Tk가 일반적으로 사용되는 방식에 적용됩니다.

해석을 고수하는 또 다른 이유는 언어 통역사가 자체 부트 스트랩 또는보다 정교하고 높은 수준의 언어에 사용될 때 부트 스트랩 프로세스 성능보다 단순성이 더 중요하기 때문입니다.

거의 모든 다른 유스 케이스의 경우 컴파일 (또는 하이브리드 접근법)이 더 적합합니다.

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