우리는 'X in list' (선형 검색, 이분 검색) 와 'X in set' 의 계산 시간을 조사했다
배경.
며칠 전 Atcorder의 ABC 167에서는 다음 문제로 TLE가 연발됐다.
・ABC167D-Teleporter
거리를 순서대로 전화 전송하고 순환할 때 멈추고 나머지 횟수는
제가 눈치챘어요. 모로 찾으면 돼요.
순환하는 ⇔가 다시 한 번 같은 도시에 와서 ⇔가 방문한 도시의 명단에
이렇게 생각하면 돼요. 파이톤X in list
에서 처리하는 데 시간이 걸려요.
그 결과 X in set
로 대체하시면 됩니다.
속도가 바뀔지 안 바뀔지 신경 쓰여서 조사 결과를 정리했다.
이른바 set형
Python에서 인용 공식 문서
set 대상은 유일한hashable 대상의 무순서 수집입니다.일반적인 용도는 귀속 테스트, 서열에서 중복, 적집, 화집, 차집, 대칭차 (배타 논리와) 등 수학 연산을 제거하는 계산을 포함한다.
컬렉션은 xin set, len(set), forxin set을 지원하는 다른 모음과 같습니다.모음에는 순서가 없기 때문에 삽입된 순서와 요소의 위치를 기록하지 않습니다.따라서 집합은 색인, 슬라이딩, 기타 순서 행위를 지원하지 않습니다.
또한 여기.에서도 간단하고 알기 쉬운 특징을 정리했다.
Python에서 인용 공식 문서
set 대상은 유일한hashable 대상의 무순서 수집입니다.일반적인 용도는 귀속 테스트, 서열에서 중복, 적집, 화집, 차집, 대칭차 (배타 논리와) 등 수학 연산을 제거하는 계산을 포함한다.
컬렉션은 xin set, len(set), forxin set을 지원하는 다른 모음과 같습니다.모음에는 순서가 없기 때문에 삽입된 순서와 요소의 위치를 기록하지 않습니다.따라서 집합은 색인, 슬라이딩, 기타 순서 행위를 지원하지 않습니다.
또한 여기.에서도 간단하고 알기 쉬운 특징을 정리했다.
같은 요소는 하나만 포함한다.
따라서 set형의 탐색은 이분 탐색을 이용하여 고속으로 변할 수 있다.
측정 조건
조사list
형set
형을 위해 다음과 같은 4가지 상황의 탐색을 조사했다.
번호 매기기
데이터 형식
데이터 순서
검색 방법
1list
무작위
선형 검색
2list
정렬됨
선형 검색
3list
정렬됨
이분 탐색
4set
(정렬됨)
(2분 탐색)
다른 조건을 동일하게 하기 위해
소스 코드
main.pyimport time
import random
from collections import deque
num = [i+1 for i in range(1000000)]
num_shaffle = random.sample(num, len(num))
num_set = set(num_shaffle)
#探す対象
target = [random.randint(1, 1000000) for i in range(10000)]
#list型線形探索またはset型
def search_seaquence(L):
each_time = deque([])
for i in range(10000):
#startからelapsed_timeまでの時間差を計測
start = time.time()
target[i] in L
elapsed_time = time.time() - start
each_time.append(elapsed_time)
return list(each_time)
#list型二分探索
def search_half(L):
each_time = deque([])
for i in range(10000):
low = 0
high = len(num) - 1
start = time.time()
while low <= high:
mid = int((low + high) // 2)
guess = L[mid]
if guess == target[i]:
break
elif guess > target[i]:
high = mid - 1
else:
low = mid + 1
elapsed_time = time.time() - start
each_time.append(elapsed_time)
return list(each_time)
def cal_time(LIS, mode):
print(mode)
#合計時間
sum_time = sum(LIS)
print ("sum_time:{0}".format(sum_time) + "[sec]")
return 0
#ランダムlist・線形探索
random_list = search_seaquence(num_shaffle)
cal_time(random_list, 'mode: random list')
#順列list・線形探索
seaquence_list_seq = search_seaquence(num)
cal_time(seaquence_list_seq, 'mode: seaquence list seaquence')
#順列list・二分探索
seaquence_list_half = search_half(num)
cal_time(seaquence_list_half, 'mode: seaquence list half')
#set探索
set_seek = search_seaquence(num_set)
cal_time(set_seek, 'mode: set')
결실
검색 방법
$10^2달러 합계 (sec)
$10^3$개 합계 (sec)
$10^4$개 합계 (sec)
무작위 선형 검색
$5.14$
$4.01\times 10$
$4.65\times 10^2$
정렬 목록 선형 검색
$1.13$
$8.36$
$1.29\times 10^2$
목록 정렬, 2분 검색
$3.46\times 10^{-3}$
$2.03\times 10^{-2}$
$1.16\times 10^{-1}$
set형
$8.44\times 10^{-5}$
$9.92\times 10^{-4}$
$5.45\times 10^{-3}$
무심결에 그것을 도표에 넣으려 했다.
(두 쌍의 도표.)
예상대로 그랬다면 이 주문은 달랐다.
나는 2분 탐색 주문이 $O(\logn)라고 생각하지만 느낌이 많이 다르다.
같은 2분 탐색set
형이라도 10달러에서 4달러면 20배가량 빠르다니 의외다.
(자기 코드가 문제일 수도 있음)
[추기] 검색 목표의 요소수를 변경한 상황에 관하여
자세히 생각해 보면 검색 목적지list
/set
의 요소수를 바꾸지 않으면 주문의 효과가 보이지 않는다
또한, 검색 목표는 10^4달러로 고정되고, 검색 목표 목록의 요소 수는 10^4, 10^5, 10^6달러입니다.
나도 변경된 상황을 조사했다.
검색 방법\목록 요소 수
$10^4$개 합계 (sec)
$10^5달러 합계 (sec)
$10^6$개 합계 (sec)
무작위 선형 검색
$1.68$
$2.58\times 10$
$5.37\times 10^2$
정렬 목록 선형 검색
$9.26\times 10^{-1}$
$1.29\times 10$
$1.34\times 10^2$
목록 정렬, 2분 검색
$8.93\times 10^{-2}$
$1.75\times 10^{-1}$
$1.76\times 10^{-1}$
set형
$5.62\times 10^{-3}$
$4.02\times 10^{-3}$
$1.01\times 10^{-2}$
(두 쌍의 도표.)
주문서와 같다.잘 됐다.
2분 탐색은 오히려 시간을 줄일 수 있는데, 이는 랜덤으로 수색 목적지를 결정하기 때문이다.
이렇게 보면 로그의 주문 강도를 알 수 있습니다.
총결산
중복 데이터를 찾을 때X in list
사용할 수 없음(경고)
그리고 역시 2분 탐색은 빠르다
대량의 데이터에서 특정한 데이터가 있는지 찾을 때도 사용할 수 있다.
다만, set
형은 인덱스 정보가 사라진다
나는 그 정보를 원할 때list
에 따로 유지하는 방법이 필요하다는 것을 알았다.
Reference
이 문제에 관하여(우리는 'X in list' (선형 검색, 이분 검색) 와 'X in set' 의 계산 시간을 조사했다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/MoriMority/items/b073f806bb350e0b1fef
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import time
import random
from collections import deque
num = [i+1 for i in range(1000000)]
num_shaffle = random.sample(num, len(num))
num_set = set(num_shaffle)
#探す対象
target = [random.randint(1, 1000000) for i in range(10000)]
#list型線形探索またはset型
def search_seaquence(L):
each_time = deque([])
for i in range(10000):
#startからelapsed_timeまでの時間差を計測
start = time.time()
target[i] in L
elapsed_time = time.time() - start
each_time.append(elapsed_time)
return list(each_time)
#list型二分探索
def search_half(L):
each_time = deque([])
for i in range(10000):
low = 0
high = len(num) - 1
start = time.time()
while low <= high:
mid = int((low + high) // 2)
guess = L[mid]
if guess == target[i]:
break
elif guess > target[i]:
high = mid - 1
else:
low = mid + 1
elapsed_time = time.time() - start
each_time.append(elapsed_time)
return list(each_time)
def cal_time(LIS, mode):
print(mode)
#合計時間
sum_time = sum(LIS)
print ("sum_time:{0}".format(sum_time) + "[sec]")
return 0
#ランダムlist・線形探索
random_list = search_seaquence(num_shaffle)
cal_time(random_list, 'mode: random list')
#順列list・線形探索
seaquence_list_seq = search_seaquence(num)
cal_time(seaquence_list_seq, 'mode: seaquence list seaquence')
#順列list・二分探索
seaquence_list_half = search_half(num)
cal_time(seaquence_list_half, 'mode: seaquence list half')
#set探索
set_seek = search_seaquence(num_set)
cal_time(set_seek, 'mode: set')
검색 방법
$10^2달러 합계 (sec)
$10^3$개 합계 (sec)
$10^4$개 합계 (sec)
무작위 선형 검색
$5.14$
$4.01\times 10$
$4.65\times 10^2$
정렬 목록 선형 검색
$1.13$
$8.36$
$1.29\times 10^2$
목록 정렬, 2분 검색
$3.46\times 10^{-3}$
$2.03\times 10^{-2}$
$1.16\times 10^{-1}$
set형
$8.44\times 10^{-5}$
$9.92\times 10^{-4}$
$5.45\times 10^{-3}$
무심결에 그것을 도표에 넣으려 했다.
(두 쌍의 도표.)
예상대로 그랬다면 이 주문은 달랐다.
나는 2분 탐색 주문이 $O(\logn)라고 생각하지만 느낌이 많이 다르다.
같은 2분 탐색
set
형이라도 10달러에서 4달러면 20배가량 빠르다니 의외다.(자기 코드가 문제일 수도 있음)
[추기] 검색 목표의 요소수를 변경한 상황에 관하여
자세히 생각해 보면 검색 목적지list
/set
의 요소수를 바꾸지 않으면 주문의 효과가 보이지 않는다
또한, 검색 목표는 10^4달러로 고정되고, 검색 목표 목록의 요소 수는 10^4, 10^5, 10^6달러입니다.
나도 변경된 상황을 조사했다.
검색 방법\목록 요소 수
$10^4$개 합계 (sec)
$10^5달러 합계 (sec)
$10^6$개 합계 (sec)
무작위 선형 검색
$1.68$
$2.58\times 10$
$5.37\times 10^2$
정렬 목록 선형 검색
$9.26\times 10^{-1}$
$1.29\times 10$
$1.34\times 10^2$
목록 정렬, 2분 검색
$8.93\times 10^{-2}$
$1.75\times 10^{-1}$
$1.76\times 10^{-1}$
set형
$5.62\times 10^{-3}$
$4.02\times 10^{-3}$
$1.01\times 10^{-2}$
(두 쌍의 도표.)
주문서와 같다.잘 됐다.
2분 탐색은 오히려 시간을 줄일 수 있는데, 이는 랜덤으로 수색 목적지를 결정하기 때문이다.
이렇게 보면 로그의 주문 강도를 알 수 있습니다.
총결산
중복 데이터를 찾을 때X in list
사용할 수 없음(경고)
그리고 역시 2분 탐색은 빠르다
대량의 데이터에서 특정한 데이터가 있는지 찾을 때도 사용할 수 있다.
다만, set
형은 인덱스 정보가 사라진다
나는 그 정보를 원할 때list
에 따로 유지하는 방법이 필요하다는 것을 알았다.
Reference
이 문제에 관하여(우리는 'X in list' (선형 검색, 이분 검색) 와 'X in set' 의 계산 시간을 조사했다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/MoriMority/items/b073f806bb350e0b1fef
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
중복 데이터를 찾을 때
X in list
사용할 수 없음(경고)그리고 역시 2분 탐색은 빠르다
대량의 데이터에서 특정한 데이터가 있는지 찾을 때도 사용할 수 있다.
다만,
set
형은 인덱스 정보가 사라진다나는 그 정보를 원할 때
list
에 따로 유지하는 방법이 필요하다는 것을 알았다.
Reference
이 문제에 관하여(우리는 'X in list' (선형 검색, 이분 검색) 와 'X in set' 의 계산 시간을 조사했다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/MoriMority/items/b073f806bb350e0b1fef텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)