December 26, 2021
python
은 사람들에게 보통 개발 속도가 빠른 대신 실행 속도가 느리다고 설명되어진다.
그래서 회사 서비스의 규모가 일정 수준을 넘어가면 java
로 넘어가야 한다는게 일반적인 정설로 굳어졌다.
python
은 정말 느릴까? 수백, 수천만 유저를 감당하지 못해서 java
로 넘어가는것이 정말 합리적일까?
궁금해서 알아보았다.
속도는 상대적이다. 따라서 느리다는 개념도 상대적이다.
그렇다면 python
이 느리다고 주장하는 사람들은 어떤 기준에서 python
이 느리다고 말하는것일까?
java
와 비교해서 알아보도록 하겠다.
벤치마크 사이트에서는 다음과 같은 결과를 보여주었다.
regex-redux | |||||
---|---|---|---|---|---|
source | secs | mem | gz | busy | cpu load |
Python 3 | 1.36 | 111,852 | 1403 | 2.64 | 32% 40% 33% 88% |
Java | 5.31 | 793,572 | 929 | 17.50 | 79% 78% 83% 89% |
pidigits | |||||
---|---|---|---|---|---|
source | secs | mem | gz | busy | cpu load |
Python 3 | 1.28 | 12,024 | 567 | 1.29 | 0% 1% 100% 0% |
Java | 0.93 | 36,088 | 764 | 0.97 | 4% 0% 1% 99% |
reverse-complement | |||||
---|---|---|---|---|---|
source | secs | mem | gz | busy | cpu load |
Python 3 | 7.20 | 1,005,184 | 814 | 10.75 | 20% 53% 48% 29% |
Java | 1.53 | 687,864 | 2183 | 3.50 | 80% 46% 57% 46% |
k-nucleotide | |||||
---|---|---|---|---|---|
source | secs | mem | gz | busy | cpu load |
Python 3 | 46.28 | 241,108 | 1967 | 176.42 | 94% 97% 95% 96% |
Java | 4.85 | 354,288 | 1812 | 15.92 | 80% 85% 87% 76% |
binary-trees | |||||
---|---|---|---|---|---|
source | secs | mem | gz | busy | cpu load |
Python 3 | 48.03 | 462,732 | 472 | 174.44 | 89% 97% 88% 89% |
Java | 2.48 | 1,725,776 | 835 | 7.86 | 74% 75% 97% 72% |
fasta | |||||
---|---|---|---|---|---|
source | secs | mem | gz | busy | cpu load |
Python 3 | 37.32 | 846,264 | 1947 | 71.03 | 10% 67% 83% 30% |
Java | 1.19 | 44,740 | 2543 | 3.50 | 75% 63% 87% 70% |
fannkuch-redux | |||||
---|---|---|---|---|---|
source | secs | mem | gz | busy | cpu load |
Python 3 | 352.29 | 12,232 | 950 | 1,392.10 | 97% 99% 100% 99% |
Java | 10.38 | 35,388 | 1282 | 40.84 | 99% 99% 98% 97% |
mandelbrot | |||||
---|---|---|---|---|---|
source | secs | mem | gz | busy | cpu load |
Python 3 | 163.32 | 12,080 | 688 | 642.00 | 98% 98% 98% 98% |
Java | 4.12 | 70,952 | 796 | 16.22 | 98% 98% 98% 99% |
spectral-norm | |||||
---|---|---|---|---|---|
source | secs | mem | gz | busy | cpu load |
Python 3 | 120.99 | 13,424 | 407 | 479.86 | 99% 99% 99% 99% |
Java | 1.58 | 39,408 | 756 | 5.97 | 94% 94% 96% 94% |
n-body | |||||
---|---|---|---|---|---|
source | secs | mem | gz | busy | cpu load |
Python 3 | 567.56 | 8,076 | 1196 | 570.95 | 0% 0% 0% 100% |
Java | 6.77 | 35,432 | 1489 | 6.82 | 100% 1% 0% 0% |
Python 3 | Python 3.9.2 |
Java | openjdk 17 2021-09-14 OpenJDK Runtime Environment (build 17+35-2724) OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing) |
실제로 정규표현식
을 제외하고는 압도적으로 java
가 더 빠르다.
그렇다면 이런 차이가 벌어지는 이유는 무엇일까?
속도 차이의 가장 큰 원인 중 한 가지는 컴파일 방식이다.
Java
는 JIT compiler
로 컴파일을 하고 python
의 여러가지 런타임 중 공식이라고 볼 수 있는 CPython
구현체의 경우는 interpreter
방식의 스크립트 언어이므로 속도에 차이가 발생한다.
하지만 python
의 또 다른 구현체인 pypy
의 경우에는 CPython
과 호환되며 JIT compiler
로 컴파일을 한다.
최근 작성된 다른 한 블로그에 의하면 pypy 3.7
의 성능이 java 8
보다 빠르거나, 근소한 차이로 느리다고 작성된 것을 확인할 수 있다.
python 에서는 멀티쓰레딩
을 지원하기 위해 GIL(Global Interpreter Lock)
을 사용한다.
하지만 GIL
특성상 실제로는 동시에 한가지 작업만 할 수 있기 때문에 쓰레드를 10개를 만들어도 단순 루프에서는 싱글스레드
보다 느린 퍼포먼스가 나온다.
단순 루프와 같은 일반적인 상황에서는 java
가 훨씬 빠르다.
하지만 우리는 단순히 100만번 +1 하며 돌아가는 루프
같은 코드를 대부분 작성하지는 않는다.
python
은 R
과 함께 데이터 사이언스 분야에서 가장 많이 사용되는 언어이다.
데이터 사이언스는 주로 엄청나게 많은 데이터를 처리하는 로직이 작성된다.
numpy
나 pandas
같은 C
로 작성된 고성능 계산 라이브러리와 함께 사용하기 때문에 많은 데이터를 처리해야하지만 속도 이슈 때문에 다른 개발 언어를 고려하지는 않는다.
머신러닝에서 가장 많이 사용되는 tensorflow
나 pytorch
와 같은 프레임워크들도 데이터 사이언스와 마찬가지로 고성능 작업이 필요하지만 중요한 병렬 연산은 CUDA
와 같은 소프트웨어가 도와주므로 속도 문제 없이 사용된다.
python
으로 작성된 fastapi
와 java
로 작성된 spring
의 multiple queries 벤치마크를 비교해보았다.
fastapi
는 183위, spring
은 122위로 20% 정도의 성능 차이를 확인할 수 있다.
하지만 아래와 같은 여러 가지 상황이 있기 때문에 단순히 벤치마크만으로 java 가 빠르기 때문에 더 좋다고 단정할 수 는 없다.
JIT compiler
로 인해 초기 오버헤드가 발생하기 때문에 cold start 가 더 느리다.한국의 경우 python 시니어 개발자보다 java 시니어 개발자가 월등히 많기 때문에 구인이 용이한 java 로 전향했을 가능성이 크다고 생각한다.
단순 알고리즘 로직에서는 성능 차이가 발생하지만 python 에서 무거운 작업을 수행할때는 대부분 C
로 작성된 고성능 라이브러리를 사용하기 때문에 성능상 문제가 발생할 일이 거의 없다.
트래픽을 감당하지 못한다면 비즈니스 로직이 최적화 되지 않았거나 아키텍쳐에 문제가 있을 가능성이 높다.
국내에도 많은 python
개발자들이 양성되었으면 좋겠다.