일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- BFSDFS
- Euler path
- Euler circuit
- Greedy
- hashing
- scc
- Dag
- Eulerian path
- bitmask
- Algospot
- Sieve_of_Eratosthenes
- Segment Tree
- Shortest path
- flows
- BST
- GCD
- graph
- backtracking
- DynamicProgramming
- disjoint-set
- CS Academy
- implementation
- 백준
- dynamic programming
- Cycle detecting
- Eulerian circuit
- POJ
- mathematics
- BOJ
- graph modeling
- Today
- Total
그냥 하는 노트와 메모장
트라이(Trie)와 자바 패키지 본문
※ 알림: 이 글은 트라이(Trie)로 자바 패키지 검색 시스템을 구현하는 것을 목적으로 두고 있습니다. 또 왜 트라이로 검색 시스템을 구축할 수 없는지를 다른 자료구조와 함께 실험을 통해 증명합니다. |
[사전 지식]
기본적으로 자바 패키지는 디렉토리 구조를 가진다. 실제로 자바 프로젝트를 생성해서 패키지를 생성하면 점(.)를 기준으로 디렉토리가 생성되고 그러한 파일 시스템을 가진다.
[상황]
각 패키지와 그 패키지에 속한 클래스들을 관리해야 한다.
이제 위 데이터를 접근하기 위해서는 먼저 정의된 패키지에 접근하여 클래스 객체에 접근할 필요가 있다. 패키지에 접근하려면 가장 적합한 자료구조는 무엇일까? 여기서 크게 세 가지 자료구조를 확인하고 성능을 체크하고자 한다.
[후보 1] 파일 시스템처럼 리스트로 관리한다.
가장 쉽고 간단한 자료구조. 하위 클래스 또는 패키지가 있고 그 클래스와 패키지들을 배열 형식으로 관리한다. 일반적으로 패키지 구조 자체가 변경되지 않기 때문에 정해진 배열 크기로 잡아도 상관없다. 단점이 있다면 특정 클래스 또는 패키지를 검색할 때 시간이 오래 걸린다. 정렬되어 있다면 이분탐색으로 O(lgN)까지 가능하다.
예상되는 시간 복잡도: O(NlgN)
예상되는 공간 복잡도: O(N)
[후보 2] 패키지 경로를 Key로 두고 Value를 클래스 리스트로 두는 HashMap으로 관리한다.
[후보 1]에서 조금 발전한 형태. 클래스 또는 패키지 검색할 때 보다 빠른 속도로 접근할 수 있다. 가령 클래스org.a.b.c.TestClass의 경우 key는 "org.a.b.c"이고 value는 ["TestClass"]가 된다.
예상되는 시간 복잡도: O(hash function)
예상되는 공간 복잡도: O(N)
[후보 3] 트라이(Trie) 구조로 관리한다. 각 노드는 패키지의 구분자 역할이다.
이 구조에서는 모든 패키지와 클래스에 대해서 경로를 구분하는 점(.) 단위로 나눠서 노드를 설정한다. 가령 클래스org.a.b.c.TestClass의 경우 노드는 총 4개가 된다. 마지막 TestClass는 패키지 경로가 아닌 클래스이므로 제외한다. 노드를 검색할 때는 해시 자료구조를 이용한다.
예상되는 시간 복잡도: O(N * (hash function))
예상되는 공간 복잡도: O(N)
눈에 보이듯 당연히 [후보 2]가 더 빠르다. 하지만 클래스, 패키지가 많아지면 hash collision으로 인해 속도가 느려지고 그로 인해 [후보 3]이 더 빠른 속도를 가지지 않을까 생각했다.
- 실험 테스트 셋 : "여기"서 다운 받으시면 된다.
- 실험 내용
후보2와 후보3을 구현하고 성능테스트를 진행한다. 위 자료구조에서는 검색이 빨라야하므로 쿼리를 변경해가며 테스트한다.
- 실험 방법
- 패키지 수 : 500, 1000, 3000, 5000, 8000, 10000, 30000, 50000, 80000, 100000, 300000, 500000개로 두고 변경하며 테스트한다.
- 쿼리 수 : 모든 패키지를 찾아본다. 즉, 쿼리의 수는 입력으로 주어진 패키지 수가 된다.
- 실험 결과
실험 결과 아래와 같이 표로 나타낼 수 있다. 단위는 초(second)다.
[결론]
어느 구간에서도 후보3이 후보2보다 빠른 곳이 없다. 따라서 특정 구분자를 가지고 있는 입력(Java 패키지 경로 같은)에 대해 굳이 트라이를 쓰지 말고 Hash+set을 사용하여 시스템을 만들자.
'Research' 카테고리의 다른 글
트리 유사도 분석 - 특징 벡터 추출 (0) | 2021.11.08 |
---|