>  기사  >  Java  >  자바가 파이썬보다 빠른 이유는 무엇입니까?

자바가 파이썬보다 빠른 이유는 무엇입니까?

(*-*)浩
(*-*)浩원래의
2019-05-16 09:30:155034검색

Python이 느린 이유는 다음과 같습니다: "GIL(Global Interpreter Lock)이기 때문에", "컴파일된 언어가 아니라 해석된 언어이기 때문에", "동적 유형 언어이기 때문에".

추천 과정: JavaTutorial.

자바가 파이썬보다 빠른 이유는 무엇입니까?

성능에 가장 큰 영향을 미치는 이유는 무엇인가요?

“GIL이니까”

현대 컴퓨터의 CPU에는 다중 코어가 있고 때로는 다중 프로세서도 있습니다. 모든 컴퓨팅 성능을 활용하기 위해 운영 체제는 스레드라는 기본 구조를 정의하며 프로세스(예: Chrome 브라우저)는 스레드를 통해 시스템 명령을 실행하기 위해 여러 스레드를 생성할 수 있습니다. 이러한 방식으로 프로세스가 많은 CPU를 사용하는 경우 컴퓨팅 로드가 여러 코어 간에 공유되어 궁극적으로 대부분의 응용 프로그램이 작업을 더 빠르게 완료할 수 있습니다.

이 글을 쓰는 시점에서 내 Chrome 브라우저에는 44개의 스레드가 열려 있습니다. 또한 POSIX 기반 운영체제(Mac OS, Linux 등)의 스레드 구조와 API는 Windows 운영체제와 다릅니다. 운영 체제는 스레드 스케줄링도 담당합니다.

멀티 스레드 프로그램을 작성해 본 적이 없다면 잠금의 개념을 이해해야 합니다. 단일 스레드 프로세스와 달리 다중 스레드 프로그래밍에서는 메모리의 변수를 변경할 때 여러 스레드가 동시에 동일한 메모리 주소를 수정하거나 액세스하려고 시도하지 않도록 해야 합니다.

CPython은 변수를 생성할 때 메모리를 할당한 다음 카운터를 사용하여 변수에 대한 참조 수를 계산합니다. 이 개념을 "참조 카운팅"이라고 합니다. 참조 수가 0이면 해당 변수는 시스템에서 해제될 수 있습니다. 이렇게 하면 "임시" 변수(예: for 루프의 컨텍스트에서)를 생성해도 애플리케이션의 메모리가 소모되지 않습니다.

계속되는 문제는 변수가 여러 스레드에서 공유되는 경우 CPython이 참조 카운터를 잠가야 한다는 것입니다. 스레드 실행을 신중하게 제어하는 ​​"전역 인터프리터 잠금"이 있습니다. 스레드 수에 관계없이 인터프리터는 한 번에 하나의 작업만 수행할 수 있습니다.

이것이 Python 애플리케이션의 성능에 어떤 영향을 미치나요?

애플리케이션이 단일 스레드, 단일 통역사인 경우 속도에 아무런 영향을 미치지 않습니다. GIL을 제거해도 코드 성능에는 영향을 미치지 않습니다.

하지만 스레드를 통해 동시성을 달성하기 위해 인터프리터(Python 프로세스)를 사용하려는 경우 스레드가 IO 집약적(즉, 네트워크 입출력 또는 디스크 입력이 많은 경우) 출력), 다음이 표시됩니다. 이 GIL 대회:

자바가 파이썬보다 빠른 이유는 무엇입니까?

웹 애플리케이션(예: Django)이 WSGI를 사용하는 경우 웹 애플리케이션으로 전송된 모든 요청은 별도의 Python 인터프리터에 의해 실행되므로 요청당 하나의 잠금만 발생합니다. Python 인터프리터는 매우 느리게 시작되므로 일부 WSGI 구현은 Python 프로세스를 오랫동안 실행하기 위해 "데몬 모드"를 지원합니다.

"인터프리트 언어이기 때문에"

이런 이유는 많이 들어봤지만 실제 작업을 지나치게 단순화한 것 같습니다. CPython.원리. 터미널에서 python myscript.py를 작성하면 CPython은 읽기, 어휘 분석, 구문 분석, 컴파일, 해석 및 실행을 포함한 긴 작업 체인을 시작합니다. 이 프로세스의 핵심은 컴파일 단계에서 .pyc 파일을 생성하고 바이트코드가 __pycache__/(Python 3인 경우) 아래의 파일에 기록되거나 소스 코드와 동일한 디렉터리에 기록된다는 것입니다. (파이썬 2). 이는 작성하는 스크립트뿐만 아니라 타사 모듈을 포함하여 가져오는 모든 코드에도 적용됩니다.

따라서 대부분의 경우(작성한 코드가 한 번만 실행되지 않는 한) Python은 바이트코드를 해석하여 로컬에서 실행합니다. 이를 Java 및 C#.NET과 비교해 보세요.

Java는 소스 코드를 "중간 언어"로 컴파일한 다음 Java 가상 머신이 바이트코드를 읽고 즉시 기계어 코드로 컴파일합니다. .NET CIL도 마찬가지입니다. .NET의 CLR(공용 언어 런타임)은 JIT(Just-In-Time) 컴파일을 사용하여 바이트코드를 기계어 코드로 컴파일합니다.

그러면 둘 다 가상 머신과 일종의 바이트코드를 사용하는데 성능 테스트에서 Python이 Java 및 C#보다 훨씬 느린 이유는 무엇입니까? 첫 번째 이유는 .NET과 Java가 JIT(Just In Time)로 컴파일되기 때문입니다.

Just-in-time 컴파일 또는 JIT(Just-in-time)에는 코드를 작은 조각(또는 프레임)으로 나누기 위한 중간 언어가 필요합니다. AOT(Ahead of Time)는 컴파일러가 소스 코드를 실행하기 전에 CPU가 이해할 수 있는 코드로 변환하는 것을 의미합니다.

JIT 자체는 동일한 바이트코드 시퀀스를 실행하기 때문에 실행 속도가 빨라지지 않습니다. 그러나 JIT는 런타임에 최적화를 수행할 수 있습니다. 좋은 GIT 최적화 프로그램은 "핫스팟"이라고 불리는 애플리케이션에서 가장 많이 실행되는 부분을 찾을 수 있습니다. 그런 다음 해당 바이트코드는 최적화되고 보다 효율적인 코드로 대체됩니다.

즉, 애플리케이션이 어떤 작업을 반복적으로 수행하면 속도가 훨씬 빨라집니다. 또한 Java와 C#은 모두 강력한 형식의 언어이므로 최적화 프로그램이 코드에 대해 더 많은 가정을 할 수 있다는 점을 잊지 마십시오.

"동적 유형 언어이기 때문입니다"

"정적 유형" 언어는 C, C++, Java, C# 및 Go 등과 같이 변수를 정의할 때 변수 유형을 지정해야 합니다.

동적 유형 언어에도 유형 개념이 있지만 변수 유형은 동적입니다.

a = 1
a = "foo"

이 예에서 Python은 동일한 이름과 유형의 str을 가진 두 번째 변수를 정의하는 동시에 a의 첫 번째 인스턴스가 차지한 메모리를 해제합니다.

정적 유형 언어는 사람들을 고문하기 위해 설계된 것이 아니라 CPU가 작동하는 방식이기 때문에 이런 식으로 설계되었습니다. 어떤 연산이 최종적으로 간단한 이진 연산으로 변환된다면 객체와 유형 모두 저수준 데이터 구조로 변환되어야 합니다.

Python은 이 모든 작업을 수행하지만 사용자는 이에 대해 신경 쓴 적이 없으며 신경 쓸 필요도 없습니다.

유형을 정의할 필요가 없다는 것이 Python이 느린 이유는 아닙니다. Python의 디자인을 사용하면 모든 것을 동적으로 만들 수 있습니다. 런타임에 객체 메서드를 바꿀 수 있고, 런타임에 기본 시스템 호출을 패치할 수 있습니다. 거의 모든 것이 가능합니다.

그리고 이 디자인은 Python을 최적화하기 어렵게 만듭니다.

그렇다면 Python의 동적 타이핑이 Python을 느리게 만드는 걸까요?

유형을 비교하고 변환하는 데 비용이 많이 듭니다. 변수를 읽거나 쓰거나 참조할 때마다 유형이 확인됩니다.

동적 유형 언어는 최적화하기 어렵습니다. Python에 대한 많은 대안이 너무 빠른 이유는 성능을 위해 편의성을 희생하기 때문입니다.

예를 들어 Cython(http://cython.org/)은 C의 정적 타이핑과 Python의 방법을 결합하여 코드의 유형을 알려줌으로써 코드를 최적화하고 84배의 성능 향상을 달성합니다

요약

파이썬이 느린 주된 이유는 역동성과 다양성 때문입니다. 다양한 문제를 해결하는 데 사용할 수 있지만 대부분의 문제에는 더 잘 최적화되고 더 빠른 솔루션이 있습니다.

그러나 Python 애플리케이션에는 비동기 사용, 성능 테스트 도구 이해, 다중 인터프리터 사용과 같은 많은 최적화 조치도 있습니다.

시작 시간이 중요하지 않고 코드가 JIT의 이점을 누릴 수 있는 애플리케이션의 경우 PyPy 사용을 고려해보세요.

성능이 중요한 코드 부분의 경우 변수가 대부분 정적으로 입력된 경우 Cython 사용을 고려해보세요.

위 내용은 자바가 파이썬보다 빠른 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.