2016-06-14 6 views
2

저는 각각 하나가 문서 ID와 관련되어있는 엄청난 양의 정수 쌍을 가지고 있습니다. 내 목표는 이제 같은 쌍을 가진 문서를 검색하는 것입니다.메모리 효율적인 맵 <pair <int,int>, 세트 <int>> 대체

Document1 

- pair1: (3, 9) 
- pair2: (5,13) 

Document2 

- pair1: (4234, 13) 
- pair2: (5,13) 

map<pair<int,int>, unordered_set<int>> hashMap 
hashMap[{3, 9}].insert(1) 
hashMap[{5, 13}].insert(1) 

hashMap[{4234, 13}].insert(2) 
hashMap[{5, 13}].insert(2) 

하는 것이 될 것입니다 :

내 첫번째 생각은 예를 들어, 즉 map<pair<int,int>, unordered_set<int>>

, 관련된 값으로 키와 쌍 값과 문서 ID를 사용하여 해시 맵 (std::map)를 사용하는 것이 었습니다 에

Key(3,9) = Documents(1) 
Key(5,13) = Documents(1,2) 
Key(4234,13) = Documents(2) 

내 문제는 이제 내 사용 가능한 24GB RAM을 초과하는 엄청난 양의 메모리가 필요하다는 것입니다. 따라서 삽입물과 조회에 좋은 성능을 제공하는 대안이 필요합니다. 이론적으로 저는 오버 헤드 비용이 고려되지 않을 때 1500 Million * 3 (PairVal1, PairVal2, Document-ID) * 4 (bytes per Integer) = 18GB을 사용하고 있습니다. 그래서 내 문제에 대한 좋은 대안이 있습니까?

+0

std :: map은 해시지도가 아닙니다. std :: unordered_map을 사용할 수도 있습니다. –

+0

효율성에 대해서는 말할 수는 없지만 stxxl에서 이러한 유형의 문제를 살펴볼 수 있습니다. http : // stxxl.sourceforge.net/ – Dan

+0

'set'의 문서 수가 적 으면'std :: vector'로 대체 할 수 있습니다 – Galik

답변

0

파일 시스템을 사용할 수 있습니까?

첫 번째 정수 다음에 오는 이름 지정 디렉토리는 두 번째 정수에 대해 각각의 이름이 지정된 텍스트 파일을 만듭니다. 텍스트 파일의 각 줄은 문서 ID가 될 수 있습니다.

모든 I/O에서 속도가 크게 저하 될 수 있습니다. 가능한 빨리 디스크를 확보하십시오. 디렉터리 이름, 파일 이름 및 파일 내용이 이진 정수 대신 ASCII 텍스트가되기 때문에 저장소 요구 사항도 상당히 증가합니다.

+0

디스크를 사용한다면 스왑 파일이나'mmap()'배후 할당기를 사용하지 않는 것이 좋을 것입니다. 파일 당 항목 수보다 훨씬 적은 오버 헤드가 있어야합니다. – joelw

+0

@joelw'mmap()'은 종종 저수준'read()'/'write()'호출보다 느리기 때문에. http://marc.info/?l=linux-kernel&m=95496636207616&w=2 –

+0

@AndrewHenle이 해결책은 저수준'read()'/'write()'가 아닙니다. 각 읽기는'open())'/'close()'쌍을 사용한다. – joelw

0

공간을 줄이기위한 하나의 해결책은 예를 들어, 대신 당신이 페어링 기능을 사용해야합니다 intstd::map<std::pair<int,int>, std::unordered_set<int>> 사용 변환 std::pair<int, int>를 들어 std::unordered_map<int, std::unordered_set<int>>

이다 :

Cantor’s Pairing Function

분명히

당신이 제한된다 당신의 쌍에서 더 작은 숫자를 사용하십시오.

최대 두 개의 16 비트 부호있는 정수 (32767, 32767)에 대한 매핑은 부호가있는 32 비트 정수의 최대 값보다 약간 큰 2147418112가됩니다.

다른 옵션은 생성, 그것은 C++로 작성된 자신의 A B 트리에 기반을 둔 인덱서, 또는 xapian 같은 오픈 소스 검색 엔진 라이브러리를 사용하고 빠르고 사용하기 쉽습니다.

Xapian은 개발자가 고급 색인 생성 및 검색 기능을 자신의 응용 프로그램에 쉽게 추가 할 수있게 해주는 고도로 적응 가능한 툴킷입니다.

+1

나는 그것에 대해 이미 생각했다. 문제는 각 쌍 값이 0에서 1 백만까지 다양 할 수 있다는 것이다. 'unsigned int '범위를 초과하는 1 백만 * 1 백만 매핑 가능성이 필요하고 unsigned long long 변수가 8 바이트를 다시 차지할 것이라고 생각했습니다. –

2

SQLite 나 BerkeleyDB 또는 Tokyo Cabinet과 같은 내장 데이터베이스의 작업 일 수 있습니다.

사용중인 데이터의 양이 RAM을 초과하는 경우 실제로 디스크에서 작동 할 수있는 것이 필요합니다.

+0

그 일을 계획하고 있었지만, 데이터베이스 경험에 대한 뒤늦은 연기는 그리 좋지 않았고, 결국에는 효과가 없었던 모든 것을 서두르고 싶지 않았습니다. 따라서 새로운 쌍을 삽입하는 데 걸리는 시간과 그 쌍이 이미 존재하는지 확인하기 전에 얼마나 오래 될지 확신 할 수 없습니다. 나는이 작업이 1,500 만 행의 비용이 많이 든다는 것을 상상할 수 있습니다. 그 일에 어떤 경험이 있습니까? –

+0

@ MadA. 비슷한 일년 전에 도쿄 캐비닛을 사용했고 초당 5 만 개를 사용했습니다. –