python

[Python] numpy와 랜덤함수

seokhyun2 2021. 4. 18. 20:45

개요

딥러닝을 하다보면, 벡터 연산을 하는 코드를 많이 짜게 됩니다. 

딥러닝을 배워서 파이썬으로 개발을 처음 하시는 분들을 보면 종종 파이썬의 기본적인 라이브러리만 활용하여 코드를 짜시는 걸 종종 보았는데요.

결론부터 말씀드리면, 그 경우 너무 느립니다.

파이썬 언어 자체가 속도가 매우 느리기 때문에, 파이썬에서는 C언어를 쉽게 연결하여 사용할 수 있는 방법이 많이 있습니다.

정말 커스텀하게 코드를 짠다면 Cython이라는 것을 사용할 수도 있고, 이미 C언어로 동작하는 라이브러리도 많이 존재합니다.

그 중에서 소개 드릴 것은 Numpy인데요.

아마 파이썬을 조금 써보신 분들은 Numpy를 많이 들어보셨을건데, 왜 써야하는 지 잘 모르시는 분들도 많으실 것 같아요.

Numpy를 써야하는 이유는 연산 속도입니다.

Numpy는 C언어로 구현되어 있는 라이브러리이기 때문에 파이썬을 그냥 사용하는 것 보다 훨씬 빠릅니다.

 

Random

그러면 이 Numpy를 아무렇게나 사용하면 항상 빠를까요?

그렇지는 않습니다.

 

랜덤을 예시로 들어보겠습니다.

파이썬에서는 기본적으로 random이라는 라이브러리가 존재합니다.

Numpy에도 random을 사용할 수 있게 되어있습니다. 

그래서 아래와 같이 코드를 짜서 비교를 해보도록 하겠습니다.

import random
import time
import numpy as np

start = time.time()
for i in range(100000):
  random.randint(1, 100000)
end = time.time()
print('randint: ', end-start)

start = time.time()
for i in range(100000):
  np.random.randint(low = 1, high=100000)
end = time.time()
print('np_randint_loop: ', end-start)

start = time.time()
np.random.randint(low=1, high=100000, size=100000)
end = time.time()
print('np_randint_bulk: ', end-start)

 

제가 실행해 본 결과는 다음과 같습니다.

randint:  0.09551692008972168
np_randint_loop:  0.23066377639770508
np_randint_bulk:  0.0011000633239746094

 

파이썬 자체 random.randint를 활용할 때는 0.095초가 걸렸는데, 오히려 np.random.randint를 활용했을 때 속도가 더 느린 걸 볼 수 있죠.

Numpy가 C언어를 사용해서 더 빠르다고 했는데, 왜 더 느릴까요?

이 부분은 반복문을 10만번 돌면서 numpy를 10만번 호출하는데, 파이썬에서 C언어로 전환하고 C언어에서 파이썬으로 전환하는 시간이 오히려 오래 걸려서 그렇습니다.

 

그래서 numpy에서는 랜덤함수를 한번에 많이 생성할 때는 위와 같이 size 파라미터를 활용하여, 한번에 여러개를 만들 수 있는 기능을 제공합니다.

그래서 np_randint_bulk 라고 출력한 수를 확인해보면, 기본 randint 보다 훨씬 빠른 걸 볼 수 있습니다.

 

그래서 Numpy라는 라이브러리가 마냥 연산 속도가 빠르다고 생각하고 아무렇게나 코드를 짜면, 오히려 그냥 파이썬 코드보다 느려질 수 있기 때문에 Numpy 라이브러리를 사용할 때는 잘 주의해서 사용해야합니다.