문서의 임의 삭제는 제재 대상으로, 문서를 삭제하려면 삭제 토론을 진행해야 합니다. 문서 보기문서 삭제토론 Python (문단 편집) === 비교적 느린 실행 속도 === 우선 기본적으로 가장 아쉬운 점은 속도이다. 한 [[https://dl.acm.org/doi/abs/10.1145/3136014.3136031|논문]]에 따르면, [[https://en.wikipedia.org/wiki/The_Computer_Language_Benchmarks_Game|CLBG]]에서 제시한 10개의 벤치마킹을 돌려본 결과 Python은 C에 비해 '''71.90'''배의 시간, '''2.80'''배의 메모리, '''75.88'''배의 에너지를 더 소모한다고 한다.[* 개발과정에서 71.90배의 실행시간 차이는 결코 무시할만한 수치가 아니다!] 느린 속도를 보완하기 위해서 보통 여러 가지 방법이 동원된다. 기본적으로는 math나 random과 같은 Python의 내장 모듈을 사용해서 멀티쓰레딩이나 멀티프로세싱을 구현한다. 다만 Python은 글로벌 락 인터프리터(GLI) 문제로 애초에 멀티프로세싱에 효율적인 타입이 아니다. 즉 멀티 프로세싱을 해도 별로 나아지지 않을 수 있다는 얘기. 혹자는 Scipy나 Numpy와 같은 모듈의 고속 계산 함수를 별도로 개발해 쓰기도(Vectorize) 한다. 더 나아가서는 속도가 빠른 C와 같은 언어를 래핑(Wrapping)하여 작성하기도 한다. 전문적으로 개발할 때는 외부 패키지에 의존하지 않고 직접 작성한 코드에서 고속화를 하기 위해 자연스럽게 더 높은 난이도의 언어를 혼합해서 개발하게 된다. 이 경우 Python은 논리적인 부분을 담당하고, 래핑된 다른 언어는 코어를 담당하게 된다. 사실 전문적인 개발회사라면 이게 일반적이다. 대표적인 예시로 Numba나 Cython같은 제3자 솔루션을 이용하기도 하며, 흔히 인공지능 용도로 사용된다고 오해받는 Python [[https://stackoverflow.com/questions/35677724/tensorflow-why-was-python-the-chosen-language|TensorFlow 는 사실 C++ 이다.]] Python 을 이용해 TensorFlow 를 '호출도' 할 수 있을뿐이다, [[https://github.com/tensorflow/tensorflow|TensorFlow 의 로직을 수정 및 커스텀 하기 위해선 반드시 C++ 코드에 손을 대야 한다.]] 이처럼 Python은 사실 다른 언어에 비해 많이 느리기 때문에 프로그래밍 대회에서 실행시간 제한 때문에 어려움을 겪기도 한다. 시스템을 건드리거나 반복 연산이 많은 것은 하기 어렵지만 python numpy 처럼 따로 모듈을 지원하기 때문에 크게 걱정할 필요는 없다. 하지만 python numpy을 사용해도 느린 건 느리다. [* Python에서는 이런 단점을 막기위해 다른 언어도 쓸수있도록 만들었다. 예시로 [[NumPy|numpy]] 모듈은 Python의 수학 모듈이지만 많은 횟수의 반복이 필요한 부분을 [[C(프로그래밍 언어)|C]]로 만들었다.] 결국 Python은 첫 교육용 언어로는 몇달 좋으나 어느정도 튜토리얼을 벗어나려면 C언어를 이용해야 한다는 이야기. 아예 C언어부터 시작하는 것이 낫다는 관점도 존재한다. GIL(Global Interpreter Lock)은 Python의 성능 저하를 얘기할 때 빼놓을 수 없다. Python은 [[쓰레드#s-3|멀티쓰레딩]]을 지원하기 위하여 GIL을 도입하여 사용하게 되었다. 따라서, python 쓰레드 10개를 만들어도 실제 Pthread/윈도우 쓰레드가 10개가 만들어지긴 하는데, GIL 때문에 개중 동시에 하나밖에 안 돌아가는 기이한 구조를 갖고 있다. 물론, 내부적으로 IO작업이 있을 시 바로 다른 쓰레드로 문맥 교환을 해주고, 바이트 코트를 100번 실행한 다음에는 인터프리터 차원에서 다른 쓰레드로 교체해 주므로 동시 작업 비슷한 효과가 난다. 이것은 구현이 매우 쉬워지고 빠른 개발을 할 수 있다는 장점이 있으나, 다중 코어 CPU가 보편화된 2006년 이후에는 다중 코어를 제대로 활용하지 못하는 구조적인 문제 때문에 HW를 이용하지 못한다는 평가를 받게 되었다. 만일 특정 프로그램에 순진하게 CPU 코어를 2개 이상 동원하려고 할 경우, 뮤텍스(MutEx), 즉 한 쓰레드에 여러 개의 CPU가 연산을 행하여 내부 정보를 오염 시키는 것을 방지하는 역할을 맡는 GIL이 병목 현상을 일으켜 코어 하나를 쓸 때보다 오히려 성능이 크게 저하된다는 것. 구글 내부에서 이미 가루가 되도록 까인 부분이다. 다만 GIL은 멀티프로세싱에서는 해당되지 않는 이야기다. 멀티프로세싱 모듈은 메모리를 완전히 분리해서 사용하기 때문이다. 일반적으로 기계어로 컴파일하여 사용하는 [[C(프로그래밍 언어)|C]], [[C++]]보다는 당연히 느리고, [[Lua]], [[PHP]]. [[JavaScript]], [[LISP]] 계열 언어 등 동적 언어들을 전체를 주욱 놓고 비교해 봐도 속도가 빠른 편은 아니다. Python처럼 가상 머신 위에서 실행되는 [[Java]], [[JavaScript]] 등의 언어들의 경우, 속도 문제를 극복하기 위해서 [[JIT]] 컴파일러를 도입했다. Python의 사실상의 표준 구현체인 CPython은 JIT 컴파일을 도입하지 않았고, JIT 컴파일을 도입한 별도의 구현체인 PyPy가 등장했다. 통계 분야 등 특정 분야에서는 [[R(프로그래밍 언어)|R]]과 같이 그 분야에 특화된 언어를 사용하는 것이 더 편리할 수도 있다. 더불어, 예전의 Python에는 CPU-bound한 쓰레드가 I/O-bound한 쓰레드와 함께 돌아갈 때, I/O-bound한 쓰레드가 실행되어야 할 상황에서도 context switch가 제대로 이루어지지 않는 문제가 있었다. 이 때문에 CPU-bound 쓰레드가 GIL을 지나치게 오래 점유하게 되면서 I/O 반응 속도가 느려지고, 다른 쓰레드는 GIL을 획득하려고 계속 시도하느라 CPU 시간을 낭비하게 되었다. 이에 대해 Python 전문가인 [[https://www.dabeaz.com/|David Beazley]]가 2009년에 [[https://archive.org/details/pyvideo_588___mindblowing-python-gil|Mindblowing Python GIL]]이라는 강연에서 지적하였다.[* [[http://www.dabeaz.com/GIL/|Beazley의 홈페이지]]에서 더 많은 시각 자료와 영상을 제공하고 있다.] 이후 Antoine Pitrou라는 개발자가 GIL을 뜯어고쳐 해당 문제를 해결하였고, [[https://docs.python.org/3.2/whatsnew/3.2.html#multi-threading|Python 3.2부터는 새로운 GIL이 적용되어서]] 성능이 어느 정도 개선되었다. 단, CPU 부하가 큰 작업을 돌리는 것이 아니면 GIL을 체감하기는 생각보다 쉽지 않다. 다중 쓰레딩으로 CPU의 여러 코어를 최대한 이용하고 싶은 경우에는 GIL가 굉장히 아쉬운 이슈지만, CPU를 별로 쓰지 않거나 I/O가 주가 되는 작업은 유의미한 성능 차이가 없다. 게다가 어설프게 코어 몇 개 깔짝깔짝 이용해서 계산하는 것보다는 그냥 C언어로 모듈을 짜서 붙이는 게 더 빠르다. 즉, python에서 CPU를 많이 먹는 부분은 C 모듈을 짜서 붙이거나, 이미 C 모듈로 짜여있는 라이브러리를 사용하거나(Numpy, Scipy 등), 필요하다면 multiprocessing 모듈을 이용하여 멀티코어를 활용하는 편. 그 이상의 CPU 부하가 큰 작업은 처음부터 [[C]], [[C++]]로 짜는 게 맞다. 하지만 대규모 연산의 멀티코어의 성능 향상을 보기 위한 것 말고도, I/O가 주가 되는 작업(즉, 여러 개의 I/O 이벤트를 기다리는 것)을 위해서 멀티쓰레드를 사용하는 경우가 많고,[* 사실 GIL 방식으로 만들 당시 싱글코어가 일반적이었다는 걸 생각해보면 싱글코어에서의 멀티쓰레딩 목적 자체가 멀티코어 성능 향상보다는 이런 다중 이벤트 루프 구현을 하기 위한 것이라고 봐야 하며, 그런 관점에서는 GIL이 합리적인 선택이었다고 할 수 있다.] 이런 경우에도 복잡한 동기화를 해야 하는 멀티쓰레딩을 사용하는 건 낭비이다. 왜냐하면 디버깅도 힘들 뿐만 아니라, 실제로는 I/O를 위해 기다리는 시간이 실제 I/O가 발생했을 때 필요한 처리 작업을 수행하는 시간보다 월등히 긴 경우가 많아 여러 개의 쓰레드를 관리하기 위한 자원만 낭비하는 꼴이기 때문이다. 따라서 [[Go(프로그래밍 언어)|Go]]나 [[Erlang]] 같은 프로그래밍 언어들은 [[코루틴]]이란 개념을 도입해[* 단, 코루틴이라는 개념 자체가 이런 최근의 프로그래밍 언어에서 처음으로 등장한 것은 아니다. 코루틴의 개념은 1950년대에 이미 나왔다.] 이러한 "event multiplexing"을 싱글쓰레드로도 구현할 수 있게 하고 있다. 특히 멀티쓰레딩할 때 필요한 각종 동기화 문제 없이 마치 싱글 쓰레드 코드를 짜는 것과 거의 동일한 방식으로 코드를 작성할 수 있으면서도 그러한 코드들이 "동시에" 동작하는 것처럼 실행해 주므로 프로그래머 입장에서 매우 편하다. 실제로는 각 이벤트에 필요한 처리를 하고 다음 이벤트가 발생하기 전까지 비는 시간에 다른 이벤트를 처리하는 코드를 실행시켜 주는 방식으로, 시분할과 비슷하지만 문맥 전환이 프로그래머가 작성한 코드에서 명시적으로 다음 이벤트를 기다려야 할 필요가 있을 때 협력적으로 발생한다는 차이점이 있다. [[C(프로그래밍 언어)|C]] 같은 언어에서 이러한 코루틴 지원이 잘 안 되는 이유는, 언어적 차원에서 함수 중간에 실행을 멈추고 다른 함수를 실행할 수 있게 해줘야 하는데 쓰레드 별로 stack이 1개밖에 없는 구조에서는 구현이 어렵고 하나의 함수로 짜야 할 내용을 여러 개의 [[callback 함수]]로 쪼개면 코드가 지저분해진다는 단점이 크기 때문이다. 이런 callback 형태를 사용하는 게 초기 [[Node.js]] 개발 환경이다. 위에서 기술한 Stackless Python에서 코루틴을 먼저 지원할 수 있었던 것도 이런 배경이 있다. 그나마 C++은 C++20에서 지원하기 시작했다. 다행히 Python은 (stackless가 아니더라도) yield 키워드를 통해 함수 실행 흐름을 제어할 수 있다. Python 3.4 버전부터는 표준 라이브러리의 각종 파일 입출력, subprocess, socket 통신 등의 기능들을 모두 코루틴화해 주는 asyncio 패키지가 기본 탑재되었다. Python 3.5 부터는 [[C##]]를 본딴 async 함수 선언자와 await 키워드가 포함되어 asyncio 라이브러리에 의존할 수밖에 없던 코루틴 기능을 다른 서드파티 라이브러리도 보다 쉽게 지원할 수 있도록 바뀌고, 코루틴 내부에서의 예외 처리 과정이 개선되었다큰 [[https://stackoverflow.com/questions/1595649/threading-in-a-pyqt-application-use-qt-threads-or-python-threads|요새는 특정 경우를 제외하면 자동으로 GIL을 on/off시켜 주는 것으로 보인다.]] 이렇게 속도를 빠르게 하려고 별별 방법을 동원한다는 것과 이를 잘 아는 사람이 드물다는 것을 감안하면, Python의 최대 단점은 기본적으로 속도가 느리다는 것과 이를 개선하기가 어렵다는 것이라고 할 수 있겠다. 이로서 파생된 문제점으로 Python에 입문하는 것은 쉽지만 마스터하긴 어렵다는 문제점이 발생한다. 이는 프로그래밍 입문만 Python으로 하고 다른 언어를 주력으로 배우고 쓰는 것으로 해결될 수도 있지만,[* 실제로 2020년대 들어서 상당수 대학교에서는 입문만 Python으로 한 후 C언어를 주력으로 가르치는 방식을 쓰기도 한다. 당연히 나름 장점이 있으니 이런 방식을 쓰는 것이다.] Python은 C 패밀리와 이질적인 문법으로 인해[* [[Java]]나 [[Javascript]], [[C++]] 같은 언어로 프로그래밍을 입문했다면, 세세한 기능이나 용도는 매우 다르지만, 적어도 문법은 C언어와 유사하기 때문에 C언어를 비롯한 다른 프로그래밍 언어를 배우는데 꽤 도움이 된다.] 다른 프로그래밍 언어를 배우는데 별 도움이 안된다는 새로운 문제가 생긴다. 당연하겠지만 Python 언어 자체를 구현하는 사람들도 느린 실행 속도가 Python의 최대 단점이라는 사실을 인식하고 있고 이를 개선하기 위해 다양한 방면에서 연구를 진행하고 있다. 후술할 PyPy와 같이 JIT컴파일을 하는 구현체를 만든 것도 그 결과물 중 하나이며, 최근에는 공식적이자 가장 호환성이 높은 CPython의 속도 또한 개선되고 있다. 2020년 Python 창시자 귀도 반 로섬은[* 후술하겠지만 Microsoft에 취직했는데, Python 속도 개선을 하겠다고 해서 기대된다.] 2021년 Python 회담(Python Language Summit)에서 버전 3.11에서는 속도를 2배 향상시키고, 향후 4년간은 속도를 5배 향상시키는 것이 목표라고 [[https://www.efinancialcareers.com/news/2021/06/python-made-faster-use-in-finance#:~:text=However%2C%20Python%27s%20creator,factor%20of%20five.%C2%A0|말했다.]] 실제로 2022년에 발표된 Python 3.11 버전에서는 상당한 속도 개선이 이루어진 것으로 [[https://docs.python.org/3.11/whatsnew/3.11.html#faster-cpython|보인다.]] 문제는 개선되었다고는 하지만 그래도 다른 프로그래밍 언어들과 비교하면 여전히 느리다는 것과 속도가 개선되는데 한계가 있다는 것이다. 이 때문에 미래에도 속도 개선이 지속적으로 이루어져야 쓸만한 속도가 나올 것으로 보인다.저장 버튼을 클릭하면 당신이 기여한 내용을 CC-BY-NC-SA 2.0 KR으로 배포하고,기여한 문서에 대한 하이퍼링크나 URL을 이용하여 저작자 표시를 하는 것으로 충분하다는 데 동의하는 것입니다.이 동의는 철회할 수 없습니다.캡챠저장미리보기