Witam Mam następujący problem: mam przechowywania łańcuchów i odpowiednią listę wartości całkowitych w MultiValueMap<String, Integer>
mam przechowującej około 13 000 000 mln struny i jeden łańcuch może mieć do 500 lub więcej wartości. Dla każdej pojedynczej wartości będę mieć dostęp losowy na mapie. Najgorszy przypadek to 13 000 000 * 500 połączeń. Teraz prędkość mapy jest dobra, ale obciążenie pamięci staje się dość wysokie. A MultiValueMap<String, Integer>
to nic innego niż HashMap/TreeMap<String, <ArrayList<Integer>>
. Zarówno HashMap, jak i TreeMap mają sporo pamięci narzutowej. Nie będę modyfikował mapy po jej zakończeniu, ale potrzebuję jej, aby była szybka i jak najmniejsza dla losowego dostępu w programie. (Przechowuję go na dysku i ładuję go na starcie, zserializowany plik mapy zajmuje około 600mb, ale w pamięci to około 3gb?)pamięci wydajny multivaluemap
najbardziej wydajna pamięć to przechowywanie ciągu w posortowanej tablicy ciągów i mają odpowiednią dwuwymiarową tablicę int dla wartości. Zatem dostęp byłby wyszukiwaniem binarnym w tablicy łańcuchów i uzyskiwaniem odpowiednich wartości.
Teraz mam trzy sposoby, aby się tam dostać:
używam posortowane MultivalueMap (TreeMap) dla fazy tworzenia do przechowywania everything.After skończę z uzyskaniem wszystkich wartości, pojawia się napis array, wywołując
map.keyset().toArray(new String[0]);
Utwórz dwuwymiarową tablicę int i uzyskaj wszystkie wartości z multivaluemap. Pro: Jest łatwy w implementacji, jest nadal szybki podczas tworzenia. Con: Zajmuje jeszcze więcej pamięci podczas kopiowania z mapy na tablice.Używam tablic lub może ArrayLists od początku i przechowywać wszystko tam Pro: najmniej narzut pamięci. Con: Byłoby to bardzo powolne, ponieważ musiałbym sortować/kopiować tablicę za każdym razem, gdy dodam nowy klucz, również musiałbym wdrożyć własne (prawdopodobnie nawet wolniejsze) sortowanie, aby zachować odpowiednią tablicę int w tej samej kolejności jak struny. Trudno wdrożyć
Używam Tablic i MultivalueMap jako bufora. Po zakończeniu programu 10% lub 20% fazy tworzenia, dodam wartości do Tablic i utrzymam je w porządku, a następnie rozpocznę nową Mapę. Pro: Proponuje się wystarczająco szybko i pamięć jest wystarczająco wydajna. Con: Trudne do wdrożenia.
Żadne z tych rozwiązań naprawdę nie wydaje mi się właściwe. Czy znasz jakieś inne rozwiązania tego problemu, być może implementacja mapy o dużej wydajności pamięci (MultiValue)?
Wiem, że mógłbym używać bazy danych, więc nie zawracaj sobie głowy umieszczaniem jej jako odpowiedzi. Chcę wiedzieć, jak mógłbym to zrobić bez korzystania z bazy danych.
Szybkie pytanie: 500 * 4 * 13 000 000 to 26 000 000 000 bajtów lub +/- 24 GB - czy rozważasz przechowywanie tych danych w zbiorze? –
Hi 500 jest najgorszym oszacowaniem przypadku, większość ciągów będzie miała tylko 1 lub 2 wartości. Teraz uruchamiam program z opcją -Xmx12g, ale przechowuję dodatkowe wartości w innej Mapie. Jak mi przykro, mapa zajmuje około 3g pamięci i około 644 MB na dysku. – samy
Sry, nie dostałem przechowywania w magazynie, po prostu googlowałem, brzmi interesująco. – samy