파이썬 스택과 큐에는 무엇을 사용해야 하는가 (각 데이터 구조의 속도 비교)
소개
이 기사는 주로 경기 프로그래밍의 이야기입니다.
Python에서 스택과 큐를 구현하는 방법은 여러 가지가 있습니다.
append()
, pop()
) append()
, pop()
) append()
, pop(0)
) append()
, popleft()
) put()
, get()
) 그런데, 이중에서 도대체 어느 것을 사용하는 것이 최적일까요.
이번은 그것을 속도면에 주목해 조사합니다.
측정 방법
각 데이터 구조에 대해 요소 추가 및 검색을 10회, 100회, 1000회, 10000회, 100000회 수행합니다.
모든 코드는 다음 import 부분을 생략합니다.
import 부분from collections import deque
from queue import Queue
import time
스택
list 사용# stack(list)
stack_list_append = []
stack_list_pop = []
for i in range(1, 6):
start = time.time()
stack_list = []
for j in range(10 ** i):
stack_list.append(j)
stack_list_append.append(time.time() - start)
start = time.time()
for j in range(10 ** i):
stack_list.pop()
stack_list_pop.append(time.time() - start)
deque 사용# stack(deque)
stack_deque_append = []
stack_deque_pop = []
for i in range(1, 6):
start = time.time()
stack_deque = deque([])
for j in range(10 ** i):
stack_deque.append(j)
stack_deque_append.append(time.time() - start)
start = time.time()
for j in range(10 ** i):
stack_deque.pop()
stack_deque_pop.append(time.time() - start)
큐
list 사용# queue(list)
queue_list_append = []
queue_list_pop = []
for i in range(1, 6):
start = time.time()
queue_list = []
for j in range(10 ** i):
queue_list.append(j)
queue_list_append.append(time.time() - start)
start = time.time()
for j in range(10 ** i):
queue_list.pop(0)
queue_list_pop.append(time.time() - start)
deque 사용# queue(deque)
queue_deque_append = []
queue_deque_pop = []
for i in range(1, 6):
start = time.time()
queue_deque = deque([])
for j in range(10 ** i):
queue_deque.append(j)
queue_deque_append.append(time.time() - start)
start = time.time()
for j in range(10 ** i):
queue_deque.popleft()
queue_deque_pop.append(time.time() - start)
Queue 사용# queue(Queue)
queue_Queue_append = []
queue_Queue_pop = []
for i in range(1, 6):
start = time.time()
queue_Queue = Queue()
for j in range(10 ** i):
queue_Queue.put(j)
queue_Queue_append.append(time.time() - start)
start = time.time()
for j in range(10 ** i):
queue_Queue.get()
queue_Queue_pop.append(time.time() - start)
측정 결과
측정 결과를 그래프로 한 결과, 다음과 같이 되었습니다.

왼쪽 상단에서 순서대로 살펴 보겠습니다.
스택 결과
요소 추가
왼쪽 상단의 그래프입니다.

약간 deque 쪽이 빠르지만 거의 같습니다.
요소 꺼내기
오른쪽 상단의 그래프입니다.

이쪽도 약간 deque 쪽이 빠릅니다만, 거의 같습니다.
대기열 결과
요소 추가
왼쪽 하단의 그래프입니다.

요소 수가 많아지면 Queue가 다른 것보다 10배 이상 느립니다.
요소 꺼내기
오른쪽 하단 그래프입니다.

Queue는 요소를 추가할 때와 동일하지만 list가 분명히 쉽습니다. 가장 빠른 deque와 비교하면 100배 이상 느려지고 있습니다.
결론
스택과 큐 모두 collections.deque를 사용하는 것이 가장 좋습니다.
모처럼이므로, 간단한 사용법도 써 둡니다.
스택
from collections import deque
s = deque([])
s.append(1) # [1]
s.append(2) # [1, 2]
s.append(3) # [1, 2, 3]
s.pop() # 一番上から取り除く [1, 2, 3] -> [1, 2]
s.pop() # [1, 2] -> [1]
s.pop() # [1] -> []
큐
스택에서는 제거할 때 pop이었던 것이, 큐라고 popleft 가 되어 있을 뿐입니다.
from collections import deque
q = deque([])
q.append(1) # [1]
q.append(2) # [1, 2]
q.append(3) # [1, 2, 3]
q.popleft() # 一番下から取り除く [1, 2, 3] -> [2, 3]
q.popleft() # [2, 3] -> [3]
q.popleft() # [3] -> []
Reference
이 문제에 관하여(파이썬 스택과 큐에는 무엇을 사용해야 하는가 (각 데이터 구조의 속도 비교)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/saba/items/107c4237206e31acdbef
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
from collections import deque
from queue import Queue
import time
# stack(list)
stack_list_append = []
stack_list_pop = []
for i in range(1, 6):
start = time.time()
stack_list = []
for j in range(10 ** i):
stack_list.append(j)
stack_list_append.append(time.time() - start)
start = time.time()
for j in range(10 ** i):
stack_list.pop()
stack_list_pop.append(time.time() - start)
# stack(deque)
stack_deque_append = []
stack_deque_pop = []
for i in range(1, 6):
start = time.time()
stack_deque = deque([])
for j in range(10 ** i):
stack_deque.append(j)
stack_deque_append.append(time.time() - start)
start = time.time()
for j in range(10 ** i):
stack_deque.pop()
stack_deque_pop.append(time.time() - start)
# queue(list)
queue_list_append = []
queue_list_pop = []
for i in range(1, 6):
start = time.time()
queue_list = []
for j in range(10 ** i):
queue_list.append(j)
queue_list_append.append(time.time() - start)
start = time.time()
for j in range(10 ** i):
queue_list.pop(0)
queue_list_pop.append(time.time() - start)
# queue(deque)
queue_deque_append = []
queue_deque_pop = []
for i in range(1, 6):
start = time.time()
queue_deque = deque([])
for j in range(10 ** i):
queue_deque.append(j)
queue_deque_append.append(time.time() - start)
start = time.time()
for j in range(10 ** i):
queue_deque.popleft()
queue_deque_pop.append(time.time() - start)
# queue(Queue)
queue_Queue_append = []
queue_Queue_pop = []
for i in range(1, 6):
start = time.time()
queue_Queue = Queue()
for j in range(10 ** i):
queue_Queue.put(j)
queue_Queue_append.append(time.time() - start)
start = time.time()
for j in range(10 ** i):
queue_Queue.get()
queue_Queue_pop.append(time.time() - start)
측정 결과를 그래프로 한 결과, 다음과 같이 되었습니다.

왼쪽 상단에서 순서대로 살펴 보겠습니다.
스택 결과
요소 추가
왼쪽 상단의 그래프입니다.

약간 deque 쪽이 빠르지만 거의 같습니다.
요소 꺼내기
오른쪽 상단의 그래프입니다.

이쪽도 약간 deque 쪽이 빠릅니다만, 거의 같습니다.
대기열 결과
요소 추가
왼쪽 하단의 그래프입니다.

요소 수가 많아지면 Queue가 다른 것보다 10배 이상 느립니다.
요소 꺼내기
오른쪽 하단 그래프입니다.

Queue는 요소를 추가할 때와 동일하지만 list가 분명히 쉽습니다. 가장 빠른 deque와 비교하면 100배 이상 느려지고 있습니다.
결론
스택과 큐 모두 collections.deque를 사용하는 것이 가장 좋습니다.
모처럼이므로, 간단한 사용법도 써 둡니다.
스택
from collections import deque
s = deque([])
s.append(1) # [1]
s.append(2) # [1, 2]
s.append(3) # [1, 2, 3]
s.pop() # 一番上から取り除く [1, 2, 3] -> [1, 2]
s.pop() # [1, 2] -> [1]
s.pop() # [1] -> []
큐
스택에서는 제거할 때 pop이었던 것이, 큐라고 popleft 가 되어 있을 뿐입니다.
from collections import deque
q = deque([])
q.append(1) # [1]
q.append(2) # [1, 2]
q.append(3) # [1, 2, 3]
q.popleft() # 一番下から取り除く [1, 2, 3] -> [2, 3]
q.popleft() # [2, 3] -> [3]
q.popleft() # [3] -> []
Reference
이 문제에 관하여(파이썬 스택과 큐에는 무엇을 사용해야 하는가 (각 데이터 구조의 속도 비교)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/saba/items/107c4237206e31acdbef
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
from collections import deque
s = deque([])
s.append(1) # [1]
s.append(2) # [1, 2]
s.append(3) # [1, 2, 3]
s.pop() # 一番上から取り除く [1, 2, 3] -> [1, 2]
s.pop() # [1, 2] -> [1]
s.pop() # [1] -> []
from collections import deque
q = deque([])
q.append(1) # [1]
q.append(2) # [1, 2]
q.append(3) # [1, 2, 3]
q.popleft() # 一番下から取り除く [1, 2, 3] -> [2, 3]
q.popleft() # [2, 3] -> [3]
q.popleft() # [3] -> []
Reference
이 문제에 관하여(파이썬 스택과 큐에는 무엇을 사용해야 하는가 (각 데이터 구조의 속도 비교)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/saba/items/107c4237206e31acdbef텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)