Skip List

7,017 views
6,535 views

Published on

스킵리스트에 대한 내용을 공부하고 소개자료를 만들어봤습니다. 잘못된 내용이나 수정할 내용에 대한 제안은 언제든지 환영합니다.

Published in: Technology
2 Comments
15 Likes
Statistics
Notes
No Downloads
Views
Total views
7,017
On SlideShare
0
From Embeds
0
Number of Embeds
104
Actions
Shares
0
Downloads
79
Comments
2
Likes
15
Embeds 0
No embeds

No notes for slide

Skip List

  1. 1. 스킵리스트- Skip List<br />
  2. 2. 스킵리스트란<br />Log시간에 검색/추가/제거를 수행할 수 있는 정렬된 자료구조<br />이진검색트리를 대체할 수 있음<br />스킵 포인터를 사용해서 빠르게 탐색 가능 - 9호선 급행처럼<br />구현이 간단함!<br />레퍼런스 없이 Red-Black Tree를 1시간 안에 구현할 수 있나요?<br />
  3. 3. 스킵리스트는 젊다!<br />1960<br />1980<br />1970<br />1990<br />Treap<br />[Aragon &<br />Seidel]<br />R Tree<br />[Guttman] <br />AVL Tree<br />[Avdelson-<br />Velskii &<br />Landis]<br />RB Tree<br />B Tree<br />[Bayer]<br />Splay Tree<br />[Sleator<br />& Tarjan]<br />Skip List<br />
  4. 4. 아이디어 : 뛰어넘기<br />빠른 검색을 위해 한 칸씩 뛰어넘으면서 찾으면 어떨까?<br />메모리 : ½ N 만큼 더 사용<br />검색 : 최대 N/2 + 1 노드를 검사<br />
  5. 5. 아이디어 : 또 뛰어넘기<br />뛰어넘기 아이디어를 또 적용하면?<br />메모리 : ¾ N만큼 더 사용<br />속도 : 최대 N/4 + 3 노드를 검사<br />
  6. 6. 아이디어 : 계속 뛰어넘기<br />2i번째 노드는2i 개의 포인터를 가지도록 만들면?<br />메모리 : N 만큼 더 사용<br />속도 : O(log N) 개의 노드만을 검사<br />여기까진 이진검색트리랑 다를 게 없음<br />
  7. 7. 동적 데이터구조로서의 문제점<br />노드를 추가하거나 삭제하면 패턴이 무너지게 됨<br />다시 패턴을 만드는 데에는 O(N)이란 긴 시간이 필요함<br />
  8. 8. 스킵리스트: 확률적 자료구조<br />크기의 확률분포를 유지하기!<br />노드 중 ½은 포인터 1개를 가짐<br />노드 중 ¼은 포인터 2개를 가짐<br />노드 중 1/2i은 포인터 i개를 가짐<br />규칙적인 패턴을 유지할 필요가 없어짐<br />하지만 여전히 높은 확률로 Log N시간에 동작함<br />struct Node<T> {<br /> T key;<br /> Node<T> *forward[];};<br />
  9. 9. 스킵리스트<br />노드 크기의 분포는 앞서 보았던 리스트와 동일<br />다만 패턴이 다르게 나타남<br />
  10. 10. 매개변수 p<br />i개의 포인터를 가진 노드가r 개라면pr개의 노드는i+1개의 포인터를 가짐<br />앞의 예제에서는 p = ½ <br />p = ½일 때 가장 속도가 빠르다!<br />적당한 속도와 메모리 효율을 위해 p = ¼ 를 권장<br />포인터의 최대 개수는 log1𝑝𝑁개가 적당<br />대부분의 구현에서는 최대 개수를 20개 정도로 고정함<br /> <br />
  11. 11. 노드 검색하기<br />
  12. 12. 노드 삽입하기<br />노드의 크기를 확률적으로 정함!<br />크기가 1이 될 확률은 (1-p)<br />크기가 2가 될 확률은 p(1-p)<br />크기가 3이 될 확률은 p2(1-p)<br />… <br />p에 따른 노드 크기의 분포<br />
  13. 13. 노드 삽입하기<br />앞쪽 포인터를 갱신하게 위해 BackLook배열을 유지하면서 탐색<br />
  14. 14. 노드 제거하기<br />같은 방식으로 BackLook배열을 유지하면서 탐색<br />제거하면서 앞뒤의 포인터를 이어줌<br />어차피 랜덤이므로 노드 크기의 분포 유지엔 영향이 없음<br />
  15. 15. 최악의 경우 O(N) 이 되지만<br />모든 노드의 크기가 같아지면 보통 리스트와 동일하게 됨.<br />하지만 길이 100짜리 리스트가 그렇게 될 확률은?<br />동전을 100번 던졌을 때 전부 앞면만 나올 확률<br />로또<br />1등먹을<br /> 확률!<br />검색시간이 기대값(Log N)의 3배 이상 걸릴 확률은 엄청나게 낮다!<br />
  16. 16. 메모리 사용량 비교<br />리스트 : 노드마다1개의 포인터 필요<br />이진검색트리: 노드마다2개의 포인터 필요<br />스킵리스트: 노드마다11−𝑝개의 포인터 필요<br />𝐸𝑋=𝑛=1∞𝑛𝑃(𝑋=𝑛)=𝑛=1∞𝑛𝑝𝑛−1(1−𝑝)=11−𝑝<br /> <br />
  17. 17. 메모리 사용량 비교<br />p의 값에 따라 메모리 사용량을 타협할 수 있음<br />더 적은 메모리 만으로도 Log 시간에 검색 가능<br />노드당포인터 사용<br />이진트리<br />리스트<br />p<br />
  18. 18. 멀티스레드에서RB트리의 문제점<br />리밸런싱은 예측할 수 없지만 무겁다 – 재수없으면 망함<br />Thread Stall<br />락<br />락<br />락<br />락(리밸런싱)<br />락<br />락<br />락<br />
  19. 19. 스킵리스트는 병렬프로그래밍에 유리함<br />락이 길어질 확률은 매우 빠르게 작아지기 때문에 불규칙한 락 때문에 모든 스레드가 멈춰버릴 확률이 적다.<br />락을 포인터/노드별로로컬하게 걸 수 있어서 충돌의 위험이 더욱 작다.<br />하지만 Persistent하게 만들기는 트리보다 어렵다.<br />
  20. 20. 언제 스킵리스트를 쓸까?<br />멀티스레드에서 자주 수정할 컨테이너가 필요할 때<br />순차적으로 탐색할 필요가 많은 경우 <br />예 : 타임라인상의 이벤트 관리<br />정렬할 필요가 없을 땐 해쉬테이블을 쓰는 것이 좋음<br />cache miss/fragmentation 등으로 인해 B-Tree보다 느리게 동작하는 경우도 있으므로 신중한 결정이 필요함<br />
  21. 21. 스킵리스트의 변형들<br />Indexed Skip List<br />엣지마다 길이를 저장해서 인덱스 접근이 가능<br />Deterministic Skip List<br />최악의 경우에도Log시간이지만 패턴 유지를 위한 비용이 필요함<br />1-2 skip list<br />바로 아래 레벨의 노드2개 이상을 지나가지 않도록 유지 <br />2-3 tree 에 대응<br />1-2-3 skip list<br />
  22. 22. 스킵리스트 구현들<br />Redis (BSD)<br />스킵리스트를 이용한 key-value 저장 서버 (ANSI C)<br />JAVA 1.6의 ConcurrentSkipListMap, Set<br />스킵리스트를 이용해 구현한 멀티스레드를 지원하는 map과 set<br />Skipdb (BSD)<br />B-Tree대신 스킵리스트를 사용해서 구현한 버클리DB 방식의 DB<br />Qt의 Qmap (GPL, LGPL)<br />Qt Framework중 GUI와 관계없는 기능을 모은 QtCore모듈에 있음<br />STL map과 유사한 방식으로 사용 가능<br />
  23. 23. Reference<br />Pugh, William (June 1990). "Skip lists: a probabilistic alternative to balanced trees".<br />Pugh, William (July 1989). “A Skip List Cookbook” <br />Herlihy et. al. “A Probably Correct Concurrent Skip List”<br />Fraser and Harris (2004). “Concurrent Programming Without Locks”<br />Wikipedia : Skip List<br />

×