ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] python sort vs numpy sort
    언어/파이썬 & 장고 2022. 8. 15. 20:44

    파이썬에서 리스트를 정렬하는 방법은 크게 내장 함수인 sort를 사용하는 것과 numpy 모듈의 sort를 사용해 진행할 수 있습니다. 방법은 다르지만 결과는 동일하게 정렬된 리스트를 받을 수 있는데 여기서 각 sort 함수의 이점을 설명해 봅니다.

    일반적으로는 numpy의 sort 함수가 내장 sort 함수보다 효율적으로 동작합니다. numpy의 sort는 기본적으로 quick sort 알고리즘을 사용하지만 merge sort와 heap sort도 사용할 수 있습니다. 그렇다면 다음과 같은 조건으로 실제 테스트를 진행하여 속도 차이가 나는지 확인해보도록 합니다.

    import timeit
    import random
    import numpy as np
    
    TEST_SIZE = 1000000
    
    array_ = [random.randint(0,TEST_SIZE) for _ in range(TEST_SIZE)]
    np_array = np.random.randint(0, TEST_SIZE, size=TEST_SIZE)
    
    def internal_sort_to_origin_array():
        sorted(array_)
    
    def np_sort_to_origin_array():
        np.sort(np.array(array_))
    
    def internal_sort_to_np_array():
        sorted(list(np_array))
    
    def np_sort_to_np_array():
        np.sort(np_array)

    테스트는 랜덤으로 100만개의 숫자를 리스트에 담고 이를 정렬하는 속도를 측정합니다. 이 때, 랜덤으로 담는 리스트는 파이썬에서 기본적으로 사용하는 list와 numpy의 array 두 가지로 준비를 하고 정렬하는 방법은 내장 함수인 sort와 numpy의 sort를 각각 실험했습니다.

    그 다음, 각각 10번씩 실행하고 걸린 결과를 평균내어 확인해 봅니다.

    REPEAT_COUNT = 10
    RUNNING_COUNT = 1
    
    t1 = timeit.repeat('internal_sort_to_origin_array()', number=RUNNING_COUNT, repeat=REPEAT_COUNT, globals=globals())
    print('internal_sort_to_origin_array: ', sum(t1) / REPEAT_COUNT)
    
    # internal_sort_to_origin_array:  0.33051503260000015
    
    t2 = timeit.repeat('np_sort_to_origin_array()', number=RUNNING_COUNT, repeat=REPEAT_COUNT, globals=globals())
    print('np_sort_to_origin_array: ', sum(t2) / REPEAT_COUNT)
    
    # np_sort_to_origin_array:  0.13641876229999986
    
    t3 = timeit.repeat('internal_sort_to_np_array()', number=RUNNING_COUNT, repeat=REPEAT_COUNT, globals=globals())
    print('internal_sort_to_np_array: ', sum(t3) / REPEAT_COUNT)
    
    # internal_sort_to_np_array:  0.8263392676999999
    
    t4 = timeit.repeat('np_sort_to_np_array()', number=RUNNING_COUNT, repeat=REPEAT_COUNT, globals=globals())
    print('np_sort_to_np_array: ', sum(t4) / REPEAT_COUNT)
    
    # np_sort_to_np_array:  0.06692215590000003

    결과는 다음과 같은 순서로 빠르게 처리되었습니다.

    numpy array를 numpy.sort > 기본 list를 numpy.sort > 기본 list를 내장 sort > numpy array를 내장 sort

    일반적으로 내장 라이브러리인 sort보다 numpy의 sort가 더 효율이 좋다는 것을 볼 수 있습니다.

    위의 결과에서 의문을 가질 수 있는 부분으로 속도가 기본 list를 내장 sort > numpy array를 내장 sort로 numpy의 array가 기본 list보다 더 느리게 동작한다는 것입니다. 일반적으로 numpy의 array가 효율적으로 저장하고 연산하는데 특화되어 있지만 정확하게는 범용함수를 사용한 연산이나 브로드캐스팅, numpy array를 활용한 처리에 효율적입니다.

    위에서는 numpy array를 일반 list로 변환한 다음, 내장 sort 함수를 실행했는데 numpy의 array와 일반 list의 구조가 다르기 때문에 변환하는 작업에서 오버헤드가 발생해 결국 가장 느린 실행 속도를 보여준 것입니다.

    결과

    대용량 리스트를 정렬하거나 연산은 numpy 모듈을 사용하는 것이 효율적

    numpy의 array를 일반 list로 변환하는 작업은 오버헤드가 발생

    댓글