Python3와 PyPy3를 비교하기 전에
컴파일 언어와 인터프리터 언어의 개념을 비교해보면 다음과 같다.
컴파일 언어 : 소스코드를 기계어로 컴파일(Compile-time) -> 실행 파일 만듬 -> 실행 (Run-time)
인터프리터 언어 : 코드를 한 줄씩 읽어가며 실행
따라서 수정상황이 발생하면, 소스 전체를 다시 컴파일 할 필요가 없고 코드 수정 후 바로 실행 가능한 것이
인터프리터 언어이다.
그렇다면 python이 어떻게 동작하는지 보자.
일반적으로 python이 C로 구현되어 있다고 알려져 있는데, 그 구현체가 CPython이다.
CPython은 가장 처음 만들어진 python 구현체이고, 인터페이스이면서 컴파일러이다.
우리가 작성하는 python 코드를 bytecode로 컴파일하고 실행한다.
다시말해, python 코드를 C언어로 바꾸는 것이 아니라 컴파일 하여 bytecode로 바꾸고,
그 다음 인터프리터가 실행한다.
참고로 Cpython 인터프리터 실행 중 단점이 있는데, GIL(Global interpreter lock)을 사용한다는 것이다.
bytecode를 실행할 때에 여러 thread를 사용할 경우, 전체에 lock을 걸어 한번에 하나의 thread만이
python 객체에 접근하도록 제한하는 것이다. 하지만 single thread일 때는 문제가 없다.
GIL 단점 보완을 위한 여러가지 방법들이 존재하고 있어 GIL로 야기하는 불편함은 거의 느끼지 못한다.
JIT 컴파일을 도입하여 CPython보다 빠르다고 알려진 PyPy 구현체를 설명하려고 한다.
PyPy3에서 사용하는 JIT(just in time) 컴파일이란 프로그램을 실행하기 전에 컴파일하는 대신,
프로그램을 실행하는 시점에서 필요한 부분들을 즉석으로 컴파일 하는 방식이고
보통 인터프리터 언어의 성능 향상을 목적으로 도입하는 경우가 많다. 인터프리트를 하면서
자주 쓰이는 코드를 캐싱하기 때문에 인터 프리터의 느린 실행속도를 개선할 수 있다.
JVM에서도 바이트 코드를 기계어로 번역할 때 JIT 컴파일러를 사용한다.
정리하면, PyPy3에서는 실행 시, 자주 쓰이는 코드를 캐싱하는 기능이 있기 때문에
즉 메모리를 조금 더 사용하여 그것들을 저장하고 있어, 실행속도를 개선할 수 있다.
간단한 코드 상에서는 Python3가 메모리, 속도 측에서 우세할 수 있는 것이고,
복잡한 코드(반복)를 사용하는 경우에서는 PyPy3가 우세하기 때문에,
코드 상황에 맞추어 두 구현체(PyPy3, Python3)를 적절하게 사용하는 것이 효율적이다.