2012-09-27 18 views
10

(Istnieje kilka pytań o czas efektywny nielicznych tablic ale szukam wydajności pamięci.)pamięci efektywny rzadki tablicy w Javie

muszę równowartość List<T> lub Map<Integer,T> który

  1. Może rosnąć na żądanie, ustawiając klucz większy niż kiedykolwiek napotkany. (Można założyć, że klucze nie są nieujemne).
  2. Jest tak wydajny pod względem pamięci, jak ArrayList<T> w przypadku, gdy większość wskaźników nie jest null, tj. Gdy rzeczywiste dane nie są bardzo rzadkie.
  3. Gdy wskaźniki są rzadkie, zużywa przestrzeń proporcjonalną do liczby indeksów innych niż null.
  4. Używa mniej pamięci niż HashMap<Integer,T> (ponieważ to autoboxuje klucze i prawdopodobnie nie korzysta z klucza skalarnego).
  5. Może uzyskać lub ustawić element w dzienniku zamortyzowanym (N), gdzie N jest liczbą pozycji: nie musi być czasem liniowym, wyszukiwanie binarne byłoby dopuszczalne.
  6. Zaimplementowane w niewirusowej, czystej bibliotece Javy (najlepiej w Maven Central).

Czy ktoś wie o takiej klasie użytkowej?

Spodziewałam się, że Commons Kolekcje będą miały jeden, ale nie wydaje się.

Natknąłem się na org.apache.commons.math.util.OpenIntToFieldHashMap, który wygląda niemal prawe, z wyjątkiem tego, że jest to typ FieldElement, który wydaje się być nieuzasadniony; Chcę tylko T extends Object. Wygląda na to, że łatwo byłoby zmienić jego kod źródłowy na bardziej ogólny, chociaż wolałbym używać zależności binarnej, jeśli jest dostępna.

Odpowiedz

6

Chciałbym spróbować z kolekcjami trove, jest TIntObjectMap, które mogą pracować dla twoich zamiarów.

+0

To wygląda dobrze. Próbowałem dostosować 'OpenIntToFieldHashMap' do ogólnego typu wartości, który wydaje się działać z ~ 10min pracy, ale działa on tylko marginalnie lepiej niż' TIntObjectMap'. –

1

Zapisałem moją walizkę testową jako jglick/inthashmap. Wyniki:

HashMap size: 1017504 
TIntObjectMap size: 853216 
IntHashMap size: 846984 
OpenIntObjectHashMap size: 760472 
+1

Gdzie mogę znaleźć IntHashMap? – oleh

+0

@oleh prawdopodobnie apache commons (?) – Karussell

+1

Przepraszam, 'IntHashMap' było moją adaptacją' OpenIntToFieldHashMap' z Commons Math. Ponieważ było to niewiele lepsze niż 'TIntObjectMap', odrzuciłem to podejście. –

4

Będę szukał inspiracji w implementacji SparseArray Androida. Możesz wyświetlić źródło, pobierając kod źródłowy AOSP tutaj http://source.android.com/source/downloading.html

+0

https://code.google.com/p/android-source-browsing/source/browse/core/java/android/util/SparseArray.java?spec=svn.platform--frameworks--base.58aff7debfdab8ca99dd6bfcfa0c7bebdf2d303b&repo=platform - framework - base & r = 58aff7debfdab8ca99dd6bfcfa0c7bebdf2d303b wygląda na odpowiedni - amortyzowany czas pracy jest nieudokumentowany, ale z inspekcji zgaduję, że jest logarytmiczny - i jest pod ASL 2.0, co jest w porządku. Niestety, nie znam tego w Central, i chciałbym, żeby był oddzielony od niepowiązanych ze sobą elementów, takich jak Android Bluetooth, który jest w tym samym źródłowym źródle. –

+1

Oto samowystarczalne wersja, która wykorzystuje wszystkie niezbędne kod z android https://github.com/frostwire/frostwire-jlibtorrent/blob/b4b3f9a90d7a1dade864d7e3eaa88b616f200a9a/src/com/frostwire/jlibtorrent/SparseArray.java – Gubatron

1

Proponuję ci użyć OpenIntObjectHashMap z biblioteki Colt. Link

+0

Dzięki za cynk . Rzeczywiście ma on umiarkowanie, ale znacznie mniejsze zużycie przestrzeni niż alternatywy. Zawarłem to w moim zmienionym przypadku testowym. –