2012-05-04 11 views
7

Widziałem wiele podobnych pytań do tego, ale nic, co naprawdę pasowało. Większość innych pytań zdawała się dotyczyć prędkości. Co mam przeżywa to pojedynczy słowniku json, który siedzi w pliku 1.1gig na moim lokalnym polu podejmowania wszystkich moich 16 gigabajtów pamięci, gdy próbuję załadować go za pomocą czegoś wzdłuż linii:Załaduj duży słownik w języku Python zakodowany jako Json bez użycia pamięci?

f = open(some_file, "rb") 
new_dictionary = json.load(f) 

Dzieje się tak niezależnie od tego, z jakiej biblioteki json korzystam (próbowałem ujson, json, yajl) i niezależnie od tego, czy czytam rzeczy w postaci strumienia bajtów, czy nie. To nie ma dla mnie żadnego sensu. Co to za zwariowane użycie pamięci i jak sobie z tym poradzić?

W przypadku, gdy jest to pomocne, słownik jest po prostu garstką zagnieżdżonych słowników, które mają ints wskazujący na inne int. Próbkę wygląda następująco:

{"0":{"3":82,"4":503,"15":456},"956":{"56":823,"678":50673,"35":1232}...} 

UPDATE: Kiedy uruchomić to z simplejson, trwa właściwie tylko 8 koncertów. Nie mam pojęcia, dlaczego ten zajmuje mniej niż wszystkie inne.

AKTUALIZACJA 2: Zrobiłem więc więcej badań. Załadowałem słownik z simplejson i próbowałem konwertować wszystkie klucze na int (według sugestii Lioriego, że łańcuchy mogą zajmować więcej miejsca). Kosmos pozostał taki sam na 8 koncertach. Potem spróbowałem sugestii Winstona Ewerta o uruchomieniu gc.collect(). Przestrzeń pozostała na 8 koncertach. W końcu, zirytowany i ciekawy, wybrałem moją nową strukturę danych, wyszedłem z Pythona i ponownie załadowałem. Lo i oto, wciąż trwa 8 koncertów. Sądzę, że Python po prostu potrzebuje tyle miejsca na duży słownik 2d. Frustrujące, na pewno, ale przynajmniej teraz wiem, że to nie jest problem z JSON, o ile użyję simplejson do załadowania go.

+0

Czy możesz powiedzieć nam więcej o tym, co znajduje się w obiekcie JSON? To znaczy. dużo list? słowniki? smyczki? pływa? Obiekty Pythona prawdopodobnie zajmą więcej pamięci niż wersja jednotarczowa, choć 16 razy więcej wydaje się podejrzaną. –

+2

W obiekcie w języku Python jest dużo narzutów. Mogę się założyć, że tyle danych zajmuje tyle miejsca. – Gabe

+0

Napisałem tę rzecz z Pythonem, i dobrze pasowało do pamięci, zanim ją napisałem. Zdecydowanie dzieje się coś dziwnego. – Eli

Odpowiedz

0

Gabe naprawdę zdobione to w komentarzu, ale ponieważ już kilka miesięcy i nie opublikował go jako odpowiedź, pomyślałem, należy po prostu odpowiedzieć na moje własne pytanie , więc potomność widzi, że istnieje odpowiedź.

W każdym razie, odpowiedź jest taka, że ​​słownik 2d zajmuje po prostu tyle miejsca w Pythonie. Każdy z tych słowników kończy się trochę miejsca nad głową, a ponieważ jest ich dużo, balansuje z 1,1 na 8 koncertów i nic nie możesz na to poradzić, prócz użycia innej struktury danych lub uzyskania więcej Baran.

+0

W rzeczywistości można użyć mniej pamięci RAM, nie ładując całego pliku w pamięci, używając analizatorów strumieniowania, ponieważ @Marco zasugerował byś działał podczas analizowania tego, co zachować w pamięci i co zrzucić. Jeśli sprawisz, że twój kod będzie trochę mądrzejszy, nie będziesz musiał kupować więcej pamięci RAM. – Pykler

0

Nie mogę uwierzyć, że zaraz to powiem, ale json to w rzeczywistości bardzo prosty format, nie byłoby zbyt trudno zbudować własny parser.

Powiedział, że to ma sens tylko wtedy, gdy:

  • Nie potrzeba pełnego słownika na końcu (czyli można spożywać dane jak go odczytać)
  • Masz dobry pomysł, jakiego rodzaju struktury danych jest (arbitralnie głębokim słowniku byłoby to znacznie trudniejsze)
2

trochę eksperymentowanie z mojej strony sugeruje, że nazywając gc.collect() po obiekcie json został przeanalizowany spada zużycie pamięci, gdzie to było kiedy obje Początkowo skonstruowano ct.

Oto wyniki otrzymam za zużycie pamięci na mniejszą skalę:

Build. No GC 
762912 
Build. GC 
763000 
Standard Json. Unicode Keys. No GC 
885216 
Standard Json. Unicode Keys. GC 
744552 
Standard Json. Int Keys. No GC 
885216 
Standard Json. Int Keys. GC 
744724 
Simple Json. Unicode Keys. No GC 
894352 
Simple Json. Unicode Keys. GC 
745520 
Simple Json. Int Keys. No GC 
894352 
Simple Json. Int Keys. GC 
744884 

Zasadniczo działa gc.collect() wydaje się porządki jakieś śmieci wytwarzających podczas procesu analizowania JSON.

Powiązane problemy