CS/언어

[Python] Pypy와 CPython (구현체)

pythaac 2021. 10. 1. 18:12

프로그래밍 언어의 구현체 (Implementation)

우리는 파이썬을 이야기할 때 종종 언어 뿐만 아니라 구현체를 포함하여 말한다. 파이썬은 다양하게 구현될 수 있는 언어의 스펙일 뿐이다.
When we speak of Python we often mean not just the language but also the implementation. Python is actually a specification for a language that can be implemented in many different ways.

  프로그래밍 언어에서 말하는 구현체란, 위와 같이 실제 언어를 구현한 방식을 말합니다. 언어라는 것은 문법과 같이 정의된 추상적인 틀이며, 이에 대한 구현에 따라 동작 방식도 성능도 달라집니다. '구현체'를 정의하는 내용이 있을까 검색해보면 JAVA의 Interface와 같은 추상클래스에 대한 구현클래스의 내용이 검색되었습니다. 프로그래밍 언어에서 언급되는 구현체도 이와 같습니다.

  파이썬의 구현체들을 살펴보면, 같은 파이썬이 구현체에 따라 다른 성능을 보이는 이유를 알 수 있습니다. 그중에서 구현체의 성능 차이로 많이 언급되는 Cpython과 Pypy의 차이를 정리해보려합니다. 그 전에 기계어와 바이트코드를 살펴봅시다.

 

기계어와 바이트코드

기계어 (Machine code / Native Code)

  • 실행속도가 빠름
    - CPU가 바로 실행할 수 있는 instruction set
  • 하드웨어 종속적
    - 모든 프로세서나 프로세서 계열은 각각 고유 instruction set을 가지고 있음

 

바이트코드 (Bytecode)

  • 실행속도가 느림
    - CPU가 아닌 VM이 실행할 수 있는 코드
  • 하드웨어 독립적
    - VM이 바이트 코드를 기계어로 번역

 

정리하면, CPU가 처리할 때 바이트코드는 VM을 거쳐 번역되므로 기계어가 훨씬 빠르지만, 바이트코드는 운영체제나 하드웨어에 종속되지 않으므로 확장성이 좋고 안전합니다. 참고로 바이트코드 생성을 위한 컴파일을 AOT(Ahead-Of-Time Compilation)이라고 합니다.

 

파이썬 구현체 (CPython과 PyPy)

CPython

  CPython은 우리가 일반적으로 사용하는 Python을 의미하며, C와 파이썬으로 작성되었습니다. CPython은 파이썬 언어의 참조 구현체라고 하는데, 파이썬 구현에 도움이 되도록 샘플과 같은 역할을 합니다.

CPython은 파이썬 컴파일러가 번역한 바이트코드를 PVM(Python Virtual Machine)에서 인터프리터 방식으로 처리하며 실행합니다. 즉, 위 그림에서 빨간색으로 표시한 부분과 같이 바이트코드를 기계어로 바꾸는 과정이 반복되고, 이 과정으로 인해 바이트코드와 기계어의 실행속도 차이가 발생합니다.

PyPy

"파이썬 코드를 빠르게 실행시키고 싶다면, PyPy를 사용하면 될겁니다" - 귀도 반 로섬 (파이썬 창시자)
“If you want your code to run faster, you should probably just use PyPy.” — Guido van Rossum (creator of Python)

  PyPy는 파이썬으로 작성된 파이썬 구현체입니다. PyPy의 가장 큰 특징은 JIT(Just-In-Time) 컴파일러를 활용했다는 점입니다. JIT 컴파일러는 컴파일러와 인터프리터 성격이 섞여 실행하는 시점(실행 즉시 컴파일한다 하여 Just-In-Time)에, 전체가 아닌 필요한 부분만 컴파일하여 기계어를 생성합니다.

  바이트 코드는 빠른 속도로 기계로 변환이 이루어지고, 이렇게 변환된 기계어 중 자주 사용하는 명령은 캐싱되어 다시 컴파일되지 않습니다. 이 부분에서 속도가 빨라지는 것을 알 수 있습니다. 캐싱된 기계어로만 프로그램이 실행된다면 바이트코드를 기계어로 번역하는 과정이 생략되어 더 빠르게 실행됩니다. 그리고, 전체 코드를 컴파일하지 않기 때문에 컴파일 시간도 단축됩니다. 물론 간단한 프로그램에서는 부분적인 컴파일도 오버헤드가 될 수 있습니다.

 

그 외 구현체

  CPython과 PyPy외에 다양한 구현체들이 있습니다. JVM에서 동작하고 Java class들을 사용하는 Jython, .NET을 위해 C#으로 작성되고 CLR(Common Language Runtime)에서 동작하는 IronPython 등등 파이썬의 구현체는 이외에도 많이 존재합니다.

 

마치며

  파이썬, 자바를 포함한 언어에는 다양한 구현체가 존재하고, 이로 인해 프로그램의 동작 방식과 성능이 차이를 보입니다. 파이썬에서 CPython과 PyPy에는 GIL(Global Interpreter Lock)이 존재하지만, IronPython에는 존재하지 않는 등 구현체에 따른 차이를 이해가 프로그래밍에서 차이를 보일 수 있습니다.

  여러 글들을 읽으면서 Python의 GIL과 Stackless Python을 살펴봐야겠다는 생각이 들었습니다.

  • GIL
  • Stackless Python
  • Abstract Syntax Tree (AST)

JVM이 Stack형식이라는 내용을 봤던 것 같은데... 계속 공부해보겠습니다!

 

 

참조

[1] 전반적인 내용

https://www.geeksforgeeks.org/difference-various-implementations-python/

[2] 위키피디아 - JIT

https://en.wikipedia.org/wiki/Just-in-time_compilation

[3] Stackless Python

https://wiki.python.org/moin/StacklessPython

[4] 블로그 - Python3와 PyPy3 차이

https://ralp0217.tistory.com/entry/Python3-%EC%99%80-PyPy3-%EC%B0%A8%EC%9D%B4

[5] 블로그 - 파이썬은 인터프리터언어입니까?

https://soooprmx.com/%ed%8c%8c%ec%9d%b4%ec%8d%ac%ec%9d%80-%ec%9d%b8%ed%84%b0%ed%94%84%eb%a6%ac%ed%84%b0%ec%96%b8%ec%96%b4%ec%9e%85%eb%8b%88%ea%b9%8c/

[6] 위키피디아 - AOT 컴파일

https://ko.wikipedia.org/wiki/AOT_%EC%BB%B4%ED%8C%8C%EC%9D%BC

[7] 위키피디아 - PyPy

https://ko.wikipedia.org/wiki/PyPy

[8] 위키피디아 - CPython

https://ko.wikipedia.org/wiki/C%ED%8C%8C%EC%9D%B4%EC%8D%AC

[9] 블로그 - How Python works?

https://velog.io/@doondoony/How-Python-works

[10] 블로그 - 파이썬은 어떻게 동작할까요?

https://www.attrest.com/learning-python-03/

[11] 나무위키 - JIT

https://namu.wiki/w/JIT

[12] 블로그 - JIT 컴파일러

https://m.blog.naver.com/ki630808/221844888233

'CS > 언어' 카테고리의 다른 글

[JAVA] Hash와 Thread-Safe  (0) 2022.01.19
[JAVA] ArrayList에서 특정 값을 가진 원소들 찾기  (0) 2022.01.14
[JAVA] Long에 대하여  (0) 2022.01.12
[JAVA] 자바의 다중상속  (0) 2022.01.11
[JAVA] POJO(Plain Old Java Object)  (0) 2022.01.06