NumPy 텐서의 결합 시간을 비교해 본다
의문
NumPy 의 텐서 ndarray 는
concatenate
또는 stack
를 사용하여 결합할 수 있습니다. 여기서, 텐서를 수시로 생성해 그들을 결합한 새로운 텐서를 요구하고 싶었을 때,어느 것이 빠릅니까? 보통으로 생각하면 단번에 결합하는 편이 빠를 것 같은 생각은 합니다만, 리스트는 어쩐지 늦다고 하는 이미지도 있습니다. 어느 쪽에서 태어난 이미지야 이거.
자, 실험해 봅시다.
대량 생성 코드
아래의 코드를
num
를 5000 씩 증가시켜 그 실행 시간을 비교해 보겠습니다.from typing import List
import datetime
import random
import time
import numpy as np
num = 5000
def listing(num: int) -> np.ndarray:
random.seed(0)
arr_list: List[np.ndarray] = []
for i in range(num):
rand1: List[List[float]] = []
for i in range(3):
rand1.append([random.random(), random.random(), random.random(),])
now_arr = np.asarray(rand1)
arr_list.append(now_arr[np.newaxis, ...])
return np.vstack(arr_list)
def stacking(num: int) -> np.ndarray:
random.seed(0)
rand2: List[List[float]] = []
for i in range(3):
rand2.append([random.random(), random.random(), random.random(),])
ret_arr = np.asarray(rand2)[np.newaxis, ...]
for i in range(num - 1):
rand3: List[List[float]] = []
for i in range(3):
rand3.append([random.random(), random.random(), random.random(),])
now_arr = np.asarray(rand3)
ret_arr = np.vstack((ret_arr,now_arr[np.newaxis, ...],))
return ret_arr
list_start_time = time.time()
list_arr = listing(num)
list_end_time = time.time()
list_elapsed_time = list_end_time - list_start_time
stack_start_time = time.time()
stack_arr = stacking(num)
stack_end_time = time.time()
stack_elapsed_time = stack_end_time - stack_start_time
print('list time: ' + str(datetime.timedelta(seconds=list_elapsed_time)))
print('stack time: ' + str(datetime.timedelta(seconds=stack_elapsed_time)))
결과는 다음과 같습니다. 역시 한 번에 결합하는 편이 빠른 것 같네요. 보고 싶어.
list
stack
5000
00:00.021
00:00.068
10000
00:00.041
00:00.186
15000
00:00.059
00:00.618
20000
00:00.080
00:02.843
25000
00:00.105
00:06.640
30000
00:00.118
00:09.918
35000
00:00.136
00:13.639
40000
00:00.157
00:18.389
45000
00:00.176
00:24.626
50000
00:00.196
00:30.691
55000
00:00.216
00:37.342
60000
00:00.234
00:44.673
65000
00:00.259
00:52.917
70000
00:00.273
01:02.477
75000
00:00.295
01:11.633
80000
00:00.317
01:21.016
85000
00:00.334
01:31.909
90000
00:00.350
01:43.772
95000
00:00.372
01:58.346
100000
00:00.409
02:09.706
한 번에 결합하는 쪽은 처리 시간이 선형으로 증가하는 반면, 매번 결합에서는 2 승에 비례하고 있는 것처럼 보입니다. 오더의 관점에서는 생성수가 많을수록 매번 결합이 불리해집니다.
소량 생성 코드
그럼, 생성수가 적은 경우는 어떨까요.
num
는 3 회로 억제하고, 그것을 100000 회 반복하여 시간을 계측해 봅니다.# 前略
times = 100000
list_start_time = time.time()
for i in range(times):
list_arr = listing(num)
list_end_time = time.time()
list_elapsed_time = list_end_time - list_start_time
stack_start_time = time.time()
for i in range(times):
stack_arr = stacking(num)
stack_end_time = time.time()
stack_elapsed_time = stack_end_time - stack_start_time
print('list time: ' + str(datetime.timedelta(seconds=list_elapsed_time)))
print('stack time: ' + str(datetime.timedelta(seconds=stack_elapsed_time)))
# list time: 0:00:02.036575
# stack time: 0:00:02.294834
이 경우에는 방금전 차이는 노골적이지는 않지만 역시 한 번에 결합하는 것이 약간 빠릅니다.
요약
어떠셨습니까? 역시 빠릅니다.
생각해 보면, 리스트가 늦을 것 같은 것은 도중에 삽입되거나 빗질했을 때에 인덱스 가는 것이 운운 같은 이야기가 대본인 생각이 들기 때문에 속공으로 소비한다면 별로 문제없는 생각도 하네요.
그럼에도 불구하고 나는 Python이나 NumPy에 관해서는 초보자도 좋은 곳이므로 이런 경우에 더 나은 실천이있을 것 같다.
Reference
이 문제에 관하여(NumPy 텐서의 결합 시간을 비교해 본다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/BlueRayi/items/e8db42ca9c6fb0e92cdd텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)