답변
거의 모든 통역사가 코드 을 직접적으로으로 해석합니다. 이는 너무 비효율적입니다. 거의 모든 해석자는 쉽게 수행 할 수있는 중간 표현을 사용합니다. 또한이 중간 코드에서 작은 최적화를 수행 할 수 있습니다.
파이썬은 다음 번에이 코드가 실행될 때 큰 이점이있는이 코드를 저장합니다. 파이썬은 더 이상 코드를 파싱 할 필요가 없습니다. 구문 분석은 컴파일 프로세스에서 가장 느린 부분입니다. 따라서, 바이트 코드 표현은 실행 오버 헤드를 상당히 실질적으로 감소시킨다.
TRS-80의 구형 MS BASIC조차도 매우 간단한 인코딩 체계를 사용했습니다. 입력하거나 줄을 편집하자마자 기본 키워드가 단일 바이트로 축소되었습니다. –
@DavidThornley : 많은 1980 년대 컴퓨터는 키워드를 토큰으로 변환했지만 숫자와 변수 이름을 텍스트 형식으로 유지하여 런타임시 값을 계산하거나 조회해야하는 MS-basic의 파생물을 사용했습니다. Atari BASIC은 변수 테이블을 만들고 이름을 인덱스로 대체하여 더 많은 처리 작업을 수행했습니다. 또한 숫자를 BCD 부동 소수점 숫자로 변환했습니다. 문자열 리터럴과 주석 만 텍스트로 저장되었습니다. 이러한 것들은 Atari BASIC이 각 라인의 숫자가 바이너리로 저장된다는 것을 제외하고는 다른 라인을 능가 할 수 있었지만 GOTO 타겟 ... – supercat
...은 BCD 부동 소수점으로 저장되었으므로 모든 GOTO는 BCD에서 이진 변환을 필요로했습니다 . 여전히 Atari BASIC의 저자가 간단히 키워드를 토큰으로 바꾸는 대신 프로그램을 파싱 된 표현으로 변환하는 것은 흥미 롭습니다. – supercat
바이트 코드를 직접 해석하는 것이 더 빠르기 때문에. 그것은 렉싱을 할 필요가 없도록하는 것입니다.
.pyc
으로 컴파일하고 여러 번 해석 할 수 있기 때문에.
그래서 여러 번 스크립트를 실행하는 경우 소스 코드를 한 번 파싱하는 오버 헤드 만 있습니다.
소스 코드를 한 번만 (처음에는 import
에 자주 올 때가 아니라) 반복하여 렉싱하고 파싱하는 것은 분명히 모호하고 무의미한 노력입니다.
그냥 ".py"파일을 실행하면 소스 코드를 계속해서 다시 렉싱하고 파싱 할 수 있습니까? 파일이 크면 상당한 오버 헤드가 될 수 있습니다. 왜 수입이 특별 대우를 받는지 나는 확신하지 못한다. 이해하는데 도움을 주시면 감사하겠습니다. – batbrat
필자는 그 이유가 성능이라는 것을 의심 스럽지만 좋은 부작용이라고 생각합니다. 나는 일부 원시 코드 문자열에서 텍스트를 찾아서 대체하는 것보다 더 높은 수준의 어셈블리 언어로 구축 된 VM이 더 실용적이라고 생각하는 것이 자연스러운 것이라고 말합니다.
편집 : 지금까지 설명하는 합리적인 의견을 떠나지 않고 내 게시물에 -1 투표를 넣어 좋아, 명확하게
는, 가상 머신 (런타임 환경)에 대해 거의 알고있다. 그것에 작은 효율 측면 (당신은 메모리 디스크 나에 바이트 코드를 저장할 수)이 있지만
나는 -1이 아니었지만, 나는 당신의 요점, 특히이 부분을 이해하지 못했다. "일부 소스 코드 문자열에서 텍스트를 찾아서 대체하는 것보다 실용적 이겠다." –
비디오보기 채널 9를 사용하거나 자신의 VM을 작성하면 두 사람이 전체 프로세스를 자세히 설명 할 수 있습니다. 그 인용구가 의미하는 바는 어셈블리보다 높은 추상화 수준에서 최적화를 수행하는 것이 때때로 쉽다는 것입니다. 이 작업을 정상적으로 수행 할 때 AST (추상 구문 트리)를 사용하면 동일한 최적화를 수행 할 수는 있지만 소스 코드를 이동 (즉, 찾기 및 바꾸기)해야하므로 실용적이지 않은 실행 환경 이런 이유로 다른 중간 표현을 사용하는 경향이 있습니다 (3 주소 코드 참조). –
바이트 코드는 AST를보다 효율적이고 간결하게 표현한 것입니다. –
은, 그 대부분은 공학 : 그것은 당신이 해석에서 구문 분석으로 구분하기 수 있습니다. 구문 분석기는 종종 가장자리 상자로 가득 찬 불쾌한 생물이 될 수 있으며 적절한 양의 미리보기를 사용하고 교대 감소 문제를 해결하는 것과 같은 비전상의 규칙을 준수해야합니다. 반대로, 해석은 정말 간단합니다. 바이트 코드의 연산 코드를 사용하는 큰 switch 문입니다.
- 1. 왜/어떻게이 컴파일합니까?
- 2. 소스를 바이트 코드로 변환하는 데 PHP APC를 사용할 수 있습니까?
- 3. 왜 이것을 컴파일합니까 (초기화 전에 함수에서 사용 했습니까)?
- 4. 왜 파이썬은 numpy.core.ma에서 질식합니까?
- 5. Objective-C는 원시 코드 또는 바이트 코드로 컴파일됩니까?
- 6. SIGABRT가이 코드로 인해 ... 왜?
- 7. 왜 비주얼하지 않은 프로젝트를 다시 컴파일합니까?
- 8. byte []를 숫자와 단락으로 해석하기
- 9. Appcelerator Titanium Mobile은 JS를 네이티브 코드로 크로스 컴파일합니까?
- 10. Android NDK 모호성, 바이트 또는 기계어 코드로 컴파일 하시겠습니까?
- 11. 왜 파이썬은 완벽하게 객체 지향적이지 않습니까?
- 12. 왜 파이썬은 파일이 존재하지 않는다고 말합니까?
- 13. 파이썬은
- 14. 파이썬은
- 15. 파이썬은
- 16. 파이썬은
- 17. 왜 "!!!"를 사용합니까? 따라 코드로
- 18. 바이너리 또는 바이트 코드로 파일 쓰기
- 19. (자바를 사용하지 않고) 자바 바이트 코드로 컴파일
- 20. 디버깅 가능한 바이트 코드로 자바 스크립트
- 21. pcap 왜 항상 8 바이트 패킷 ... 왜?
- 22. Subversion 커밋을하기 전에 소스를 어떻게 위생 처리합니까?
- 23. 파이썬은 버튼
- 24. URL에 상대 경로 해석하기
- 25. 텍스트 입력을 PHP로 해석하기
- 26. ListView에서 항목 해석하기
- 27. jQuery.ajax로 응답을 오류로 해석하기
- 28. 왜 Mercurial은 데이터를 푸시하기 전에 인증하지 않습니까?
- 29. 왜 이미지가 바이트 배열로 표시됩니까?
- 30. 파이썬 VM은 매번 메소드를 컴파일합니까?
나에게 숙제가 들립니다. –